home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / share / gettext / intl / vasnprintf.c < prev    next >
Encoding:
C/C++ Source or Header  |  2010-09-19  |  217.1 KB  |  5,569 lines

  1. /* vsprintf with automatic memory allocation.
  2.    Copyright (C) 1999, 2002-2010 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify it
  5.    under the terms of the GNU Library General Public License as published
  6.    by the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12.    Library General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU Library General Public
  15.    License along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
  17.    USA.  */
  18.  
  19. /* This file can be parametrized with the following macros:
  20.      VASNPRINTF         The name of the function being defined.
  21.      FCHAR_T            The element type of the format string.
  22.      DCHAR_T            The element type of the destination (result) string.
  23.      FCHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters
  24.                         in the format string are ASCII. MUST be set if
  25.                         FCHAR_T and DCHAR_T are not the same type.
  26.      DIRECTIVE          Structure denoting a format directive.
  27.                         Depends on FCHAR_T.
  28.      DIRECTIVES         Structure denoting the set of format directives of a
  29.                         format string.  Depends on FCHAR_T.
  30.      PRINTF_PARSE       Function that parses a format string.
  31.                         Depends on FCHAR_T.
  32.      DCHAR_CPY          memcpy like function for DCHAR_T[] arrays.
  33.      DCHAR_SET          memset like function for DCHAR_T[] arrays.
  34.      DCHAR_MBSNLEN      mbsnlen like function for DCHAR_T[] arrays.
  35.      SNPRINTF           The system's snprintf (or similar) function.
  36.                         This may be either snprintf or swprintf.
  37.      TCHAR_T            The element type of the argument and result string
  38.                         of the said SNPRINTF function.  This may be either
  39.                         char or wchar_t.  The code exploits that
  40.                         sizeof (TCHAR_T) | sizeof (DCHAR_T) and
  41.                         alignof (TCHAR_T) <= alignof (DCHAR_T).
  42.      DCHAR_IS_TCHAR     Set to 1 if DCHAR_T and TCHAR_T are the same type.
  43.      DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[].
  44.      DCHAR_IS_UINT8_T   Set to 1 if DCHAR_T is uint8_t.
  45.      DCHAR_IS_UINT16_T  Set to 1 if DCHAR_T is uint16_t.
  46.      DCHAR_IS_UINT32_T  Set to 1 if DCHAR_T is uint32_t.  */
  47.  
  48. /* Tell glibc's <stdio.h> to provide a prototype for snprintf().
  49.    This must come before <config.h> because <config.h> may include
  50.    <features.h>, and once <features.h> has been included, it's too late.  */
  51. #ifndef _GNU_SOURCE
  52. # define _GNU_SOURCE    1
  53. #endif
  54.  
  55. #ifndef VASNPRINTF
  56. # include <config.h>
  57. #endif
  58. #ifndef IN_LIBINTL
  59. # include <alloca.h>
  60. #endif
  61.  
  62. /* Specification.  */
  63. #ifndef VASNPRINTF
  64. # if WIDE_CHAR_VERSION
  65. #  include "vasnwprintf.h"
  66. # else
  67. #  include "vasnprintf.h"
  68. # endif
  69. #endif
  70.  
  71. #include <locale.h>     /* localeconv() */
  72. #include <stdio.h>      /* snprintf(), sprintf() */
  73. #include <stdlib.h>     /* abort(), malloc(), realloc(), free() */
  74. #include <string.h>     /* memcpy(), strlen() */
  75. #include <errno.h>      /* errno */
  76. #include <limits.h>     /* CHAR_BIT */
  77. #include <float.h>      /* DBL_MAX_EXP, LDBL_MAX_EXP */
  78. #if HAVE_NL_LANGINFO
  79. # include <langinfo.h>
  80. #endif
  81. #ifndef VASNPRINTF
  82. # if WIDE_CHAR_VERSION
  83. #  include "wprintf-parse.h"
  84. # else
  85. #  include "printf-parse.h"
  86. # endif
  87. #endif
  88.  
  89. /* Checked size_t computations.  */
  90. #include "xsize.h"
  91.  
  92. #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
  93. # include <math.h>
  94. # include "float+.h"
  95. #endif
  96.  
  97. #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
  98. # include <math.h>
  99. # include "isnand-nolibm.h"
  100. #endif
  101.  
  102. #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) && !defined IN_LIBINTL
  103. # include <math.h>
  104. # include "isnanl-nolibm.h"
  105. # include "fpucw.h"
  106. #endif
  107.  
  108. #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
  109. # include <math.h>
  110. # include "isnand-nolibm.h"
  111. # include "printf-frexp.h"
  112. #endif
  113.  
  114. #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
  115. # include <math.h>
  116. # include "isnanl-nolibm.h"
  117. # include "printf-frexpl.h"
  118. # include "fpucw.h"
  119. #endif
  120.  
  121. /* Default parameters.  */
  122. #ifndef VASNPRINTF
  123. # if WIDE_CHAR_VERSION
  124. #  define VASNPRINTF vasnwprintf
  125. #  define FCHAR_T wchar_t
  126. #  define DCHAR_T wchar_t
  127. #  define TCHAR_T wchar_t
  128. #  define DCHAR_IS_TCHAR 1
  129. #  define DIRECTIVE wchar_t_directive
  130. #  define DIRECTIVES wchar_t_directives
  131. #  define PRINTF_PARSE wprintf_parse
  132. #  define DCHAR_CPY wmemcpy
  133. #  define DCHAR_SET wmemset
  134. # else
  135. #  define VASNPRINTF vasnprintf
  136. #  define FCHAR_T char
  137. #  define DCHAR_T char
  138. #  define TCHAR_T char
  139. #  define DCHAR_IS_TCHAR 1
  140. #  define DIRECTIVE char_directive
  141. #  define DIRECTIVES char_directives
  142. #  define PRINTF_PARSE printf_parse
  143. #  define DCHAR_CPY memcpy
  144. #  define DCHAR_SET memset
  145. # endif
  146. #endif
  147. #if WIDE_CHAR_VERSION
  148.   /* TCHAR_T is wchar_t.  */
  149. # define USE_SNPRINTF 1
  150. # if HAVE_DECL__SNWPRINTF
  151.    /* On Windows, the function swprintf() has a different signature than
  152.       on Unix; we use the function _snwprintf() or - on mingw - snwprintf()
  153.       instead.  The mingw function snwprintf() has fewer bugs than the
  154.       MSVCRT function _snwprintf(), so prefer that.  */
  155. #  if defined __MINGW32__
  156. #   define SNPRINTF snwprintf
  157. #  else
  158. #   define SNPRINTF _snwprintf
  159. #  endif
  160. # else
  161.    /* Unix.  */
  162. #  define SNPRINTF swprintf
  163. # endif
  164. #else
  165.   /* TCHAR_T is char.  */
  166.   /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'.
  167.      But don't use it on BeOS, since BeOS snprintf produces no output if the
  168.      size argument is >= 0x3000000.
  169.      Also don't use it on Linux libc5, since there snprintf with size = 1
  170.      writes any output without bounds, like sprintf.  */
  171. # if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__ && !(__GNU_LIBRARY__ == 1)
  172. #  define USE_SNPRINTF 1
  173. # else
  174. #  define USE_SNPRINTF 0
  175. # endif
  176. # if HAVE_DECL__SNPRINTF
  177.    /* Windows.  The mingw function snprintf() has fewer bugs than the MSVCRT
  178.       function _snprintf(), so prefer that.  */
  179. #  if defined __MINGW32__
  180. #   define SNPRINTF snprintf
  181.     /* Here we need to call the native snprintf, not rpl_snprintf.  */
  182. #   undef snprintf
  183. #  else
  184. #   define SNPRINTF _snprintf
  185. #  endif
  186. # else
  187.    /* Unix.  */
  188. #  define SNPRINTF snprintf
  189.    /* Here we need to call the native snprintf, not rpl_snprintf.  */
  190. #  undef snprintf
  191. # endif
  192. #endif
  193. /* Here we need to call the native sprintf, not rpl_sprintf.  */
  194. #undef sprintf
  195.  
  196. /* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized"
  197.    warnings in this file.  Use -Dlint to suppress them.  */
  198. #ifdef lint
  199. # define IF_LINT(Code) Code
  200. #else
  201. # define IF_LINT(Code) /* empty */
  202. #endif
  203.  
  204. /* Avoid some warnings from "gcc -Wshadow".
  205.    This file doesn't use the exp() and remainder() functions.  */
  206. #undef exp
  207. #define exp expo
  208. #undef remainder
  209. #define remainder rem
  210.  
  211. #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && !WIDE_CHAR_VERSION
  212. # if (HAVE_STRNLEN && !defined _AIX)
  213. #  define local_strnlen strnlen
  214. # else
  215. #  ifndef local_strnlen_defined
  216. #   define local_strnlen_defined 1
  217. static size_t
  218. local_strnlen (const char *string, size_t maxlen)
  219. {
  220.   const char *end = memchr (string, '\0', maxlen);
  221.   return end ? (size_t) (end - string) : maxlen;
  222. }
  223. #  endif
  224. # endif
  225. #endif
  226.  
  227. #if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)) && HAVE_WCHAR_T
  228. # if HAVE_WCSLEN
  229. #  define local_wcslen wcslen
  230. # else
  231.    /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
  232.       a dependency towards this library, here is a local substitute.
  233.       Define this substitute only once, even if this file is included
  234.       twice in the same compilation unit.  */
  235. #  ifndef local_wcslen_defined
  236. #   define local_wcslen_defined 1
  237. static size_t
  238. local_wcslen (const wchar_t *s)
  239. {
  240.   const wchar_t *ptr;
  241.  
  242.   for (ptr = s; *ptr != (wchar_t) 0; ptr++)
  243.     ;
  244.   return ptr - s;
  245. }
  246. #  endif
  247. # endif
  248. #endif
  249.  
  250. #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && HAVE_WCHAR_T && WIDE_CHAR_VERSION
  251. # if HAVE_WCSNLEN
  252. #  define local_wcsnlen wcsnlen
  253. # else
  254. #  ifndef local_wcsnlen_defined
  255. #   define local_wcsnlen_defined 1
  256. static size_t
  257. local_wcsnlen (const wchar_t *s, size_t maxlen)
  258. {
  259.   const wchar_t *ptr;
  260.  
  261.   for (ptr = s; maxlen > 0 && *ptr != (wchar_t) 0; ptr++, maxlen--)
  262.     ;
  263.   return ptr - s;
  264. }
  265. #  endif
  266. # endif
  267. #endif
  268.  
  269. #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
  270. /* Determine the decimal-point character according to the current locale.  */
  271. # ifndef decimal_point_char_defined
  272. #  define decimal_point_char_defined 1
  273. static char
  274. decimal_point_char (void)
  275. {
  276.   const char *point;
  277.   /* Determine it in a multithread-safe way.  We know nl_langinfo is
  278.      multithread-safe on glibc systems and MacOS X systems, but is not required
  279.      to be multithread-safe by POSIX.  sprintf(), however, is multithread-safe.
  280.      localeconv() is rarely multithread-safe.  */
  281. #  if HAVE_NL_LANGINFO && (__GLIBC__ || (defined __APPLE__ && defined __MACH__))
  282.   point = nl_langinfo (RADIXCHAR);
  283. #  elif 1
  284.   char pointbuf[5];
  285.   sprintf (pointbuf, "%#.0f", 1.0);
  286.   point = &pointbuf[1];
  287. #  else
  288.   point = localeconv () -> decimal_point;
  289. #  endif
  290.   /* The decimal point is always a single byte: either '.' or ','.  */
  291.   return (point[0] != '\0' ? point[0] : '.');
  292. }
  293. # endif
  294. #endif
  295.  
  296. #if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE && !defined IN_LIBINTL
  297.  
  298. /* Equivalent to !isfinite(x) || x == 0, but does not require libm.  */
  299. static int
  300. is_infinite_or_zero (double x)
  301. {
  302.   return isnand (x) || x + x == x;
  303. }
  304.  
  305. #endif
  306.  
  307. #if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL
  308.  
  309. /* Equivalent to !isfinite(x) || x == 0, but does not require libm.  */
  310. static int
  311. is_infinite_or_zerol (long double x)
  312. {
  313.   return isnanl (x) || x + x == x;
  314. }
  315.  
  316. #endif
  317.  
  318. #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
  319.  
  320. /* Converting 'long double' to decimal without rare rounding bugs requires
  321.    real bignums.  We use the naming conventions of GNU gmp, but vastly simpler
  322.    (and slower) algorithms.  */
  323.  
  324. typedef unsigned int mp_limb_t;
  325. # define GMP_LIMB_BITS 32
  326. typedef int mp_limb_verify[2 * (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS) - 1];
  327.  
  328. typedef unsigned long long mp_twolimb_t;
  329. # define GMP_TWOLIMB_BITS 64
  330. typedef int mp_twolimb_verify[2 * (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS) - 1];
  331.  
  332. /* Representation of a bignum >= 0.  */
  333. typedef struct
  334. {
  335.   size_t nlimbs;
  336.   mp_limb_t *limbs; /* Bits in little-endian order, allocated with malloc().  */
  337. } mpn_t;
  338.  
  339. /* Compute the product of two bignums >= 0.
  340.    Return the allocated memory in case of success, NULL in case of memory
  341.    allocation failure.  */
  342. static void *
  343. multiply (mpn_t src1, mpn_t src2, mpn_t *dest)
  344. {
  345.   const mp_limb_t *p1;
  346.   const mp_limb_t *p2;
  347.   size_t len1;
  348.   size_t len2;
  349.  
  350.   if (src1.nlimbs <= src2.nlimbs)
  351.     {
  352.       len1 = src1.nlimbs;
  353.       p1 = src1.limbs;
  354.       len2 = src2.nlimbs;
  355.       p2 = src2.limbs;
  356.     }
  357.   else
  358.     {
  359.       len1 = src2.nlimbs;
  360.       p1 = src2.limbs;
  361.       len2 = src1.nlimbs;
  362.       p2 = src1.limbs;
  363.     }
  364.   /* Now 0 <= len1 <= len2.  */
  365.   if (len1 == 0)
  366.     {
  367.       /* src1 or src2 is zero.  */
  368.       dest->nlimbs = 0;
  369.       dest->limbs = (mp_limb_t *) malloc (1);
  370.     }
  371.   else
  372.     {
  373.       /* Here 1 <= len1 <= len2.  */
  374.       size_t dlen;
  375.       mp_limb_t *dp;
  376.       size_t k, i, j;
  377.  
  378.       dlen = len1 + len2;
  379.       dp = (mp_limb_t *) malloc (dlen * sizeof (mp_limb_t));
  380.       if (dp == NULL)
  381.         return NULL;
  382.       for (k = len2; k > 0; )
  383.         dp[--k] = 0;
  384.       for (i = 0; i < len1; i++)
  385.         {
  386.           mp_limb_t digit1 = p1[i];
  387.           mp_twolimb_t carry = 0;
  388.           for (j = 0; j < len2; j++)
  389.             {
  390.               mp_limb_t digit2 = p2[j];
  391.               carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
  392.               carry += dp[i + j];
  393.               dp[i + j] = (mp_limb_t) carry;
  394.               carry = carry >> GMP_LIMB_BITS;
  395.             }
  396.           dp[i + len2] = (mp_limb_t) carry;
  397.         }
  398.       /* Normalise.  */
  399.       while (dlen > 0 && dp[dlen - 1] == 0)
  400.         dlen--;
  401.       dest->nlimbs = dlen;
  402.       dest->limbs = dp;
  403.     }
  404.   return dest->limbs;
  405. }
  406.  
  407. /* Compute the quotient of a bignum a >= 0 and a bignum b > 0.
  408.    a is written as  a = q * b + r  with 0 <= r < b.  q is the quotient, r
  409.    the remainder.
  410.    Finally, round-to-even is performed: If r > b/2 or if r = b/2 and q is odd,
  411.    q is incremented.
  412.    Return the allocated memory in case of success, NULL in case of memory
  413.    allocation failure.  */
  414. static void *
  415. divide (mpn_t a, mpn_t b, mpn_t *q)
  416. {
  417.   /* Algorithm:
  418.      First normalise a and b: a=[a[m-1],...,a[0]], b=[b[n-1],...,b[0]]
  419.      with m>=0 and n>0 (in base beta = 2^GMP_LIMB_BITS).
  420.      If m<n, then q:=0 and r:=a.
  421.      If m>=n=1, perform a single-precision division:
  422.        r:=0, j:=m,
  423.        while j>0 do
  424.          {Here (q[m-1]*beta^(m-1)+...+q[j]*beta^j) * b[0] + r*beta^j =
  425.                = a[m-1]*beta^(m-1)+...+a[j]*beta^j und 0<=r<b[0]<beta}
  426.          j:=j-1, r:=r*beta+a[j], q[j]:=floor(r/b[0]), r:=r-b[0]*q[j].
  427.        Normalise [q[m-1],...,q[0]], yields q.
  428.      If m>=n>1, perform a multiple-precision division:
  429.        We have a/b < beta^(m-n+1).
  430.        s:=intDsize-1-(highest bit in b[n-1]), 0<=s<intDsize.
  431.        Shift a and b left by s bits, copying them. r:=a.
  432.        r=[r[m],...,r[0]], b=[b[n-1],...,b[0]] with b[n-1]>=beta/2.
  433.        For j=m-n,...,0: {Here 0 <= r < b*beta^(j+1).}
  434.          Compute q* :
  435.            q* := floor((r[j+n]*beta+r[j+n-1])/b[n-1]).
  436.            In case of overflow (q* >= beta) set q* := beta-1.
  437.            Compute c2 := ((r[j+n]*beta+r[j+n-1]) - q* * b[n-1])*beta + r[j+n-2]
  438.            and c3 := b[n-2] * q*.
  439.            {We have 0 <= c2 < 2*beta^2, even 0 <= c2 < beta^2 if no overflow
  440.             occurred.  Furthermore 0 <= c3 < beta^2.
  441.             If there was overflow and
  442.             r[j+n]*beta+r[j+n-1] - q* * b[n-1] >= beta, i.e. c2 >= beta^2,
  443.             the next test can be skipped.}
  444.            While c3 > c2, {Here 0 <= c2 < c3 < beta^2}
  445.              Put q* := q* - 1, c2 := c2 + b[n-1]*beta, c3 := c3 - b[n-2].
  446.            If q* > 0:
  447.              Put r := r - b * q* * beta^j. In detail:
  448.                [r[n+j],...,r[j]] := [r[n+j],...,r[j]] - q* * [b[n-1],...,b[0]].
  449.                hence: u:=0, for i:=0 to n-1 do
  450.                               u := u + q* * b[i],
  451.                               r[j+i]:=r[j+i]-(u mod beta) (+ beta, if carry),
  452.                               u:=u div beta (+ 1, if carry in subtraction)
  453.                       r[n+j]:=r[n+j]-u.
  454.                {Since always u = (q* * [b[i-1],...,b[0]] div beta^i) + 1
  455.                                < q* + 1 <= beta,
  456.                 the carry u does not overflow.}
  457.              If a negative carry occurs, put q* := q* - 1
  458.                and [r[n+j],...,r[j]] := [r[n+j],...,r[j]] + [0,b[n-1],...,b[0]].
  459.          Set q[j] := q*.
  460.        Normalise [q[m-n],..,q[0]]; this yields the quotient q.
  461.        Shift [r[n-1],...,r[0]] right by s bits and normalise; this yields the
  462.        rest r.
  463.        The room for q[j] can be allocated at the memory location of r[n+j].
  464.      Finally, round-to-even:
  465.        Shift r left by 1 bit.
  466.        If r > b or if r = b and q[0] is odd, q := q+1.
  467.    */
  468.   const mp_limb_t *a_ptr = a.limbs;
  469.   size_t a_len = a.nlimbs;
  470.   const mp_limb_t *b_ptr = b.limbs;
  471.   size_t b_len = b.nlimbs;
  472.   mp_limb_t *roomptr;
  473.   mp_limb_t *tmp_roomptr = NULL;
  474.   mp_limb_t *q_ptr;
  475.   size_t q_len;
  476.   mp_limb_t *r_ptr;
  477.   size_t r_len;
  478.  
  479.   /* Allocate room for a_len+2 digits.
  480.      (Need a_len+1 digits for the real division and 1 more digit for the
  481.      final rounding of q.)  */
  482.   roomptr = (mp_limb_t *) malloc ((a_len + 2) * sizeof (mp_limb_t));
  483.   if (roomptr == NULL)
  484.     return NULL;
  485.  
  486.   /* Normalise a.  */
  487.   while (a_len > 0 && a_ptr[a_len - 1] == 0)
  488.     a_len--;
  489.  
  490.   /* Normalise b.  */
  491.   for (;;)
  492.     {
  493.       if (b_len == 0)
  494.         /* Division by zero.  */
  495.         abort ();
  496.       if (b_ptr[b_len - 1] == 0)
  497.         b_len--;
  498.       else
  499.         break;
  500.     }
  501.  
  502.   /* Here m = a_len >= 0 and n = b_len > 0.  */
  503.  
  504.   if (a_len < b_len)
  505.     {
  506.       /* m<n: trivial case.  q=0, r := copy of a.  */
  507.       r_ptr = roomptr;
  508.       r_len = a_len;
  509.       memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
  510.       q_ptr = roomptr + a_len;
  511.       q_len = 0;
  512.     }
  513.   else if (b_len == 1)
  514.     {
  515.       /* n=1: single precision division.
  516.          beta^(m-1) <= a < beta^m  ==>  beta^(m-2) <= a/b < beta^m  */
  517.       r_ptr = roomptr;
  518.       q_ptr = roomptr + 1;
  519.       {
  520.         mp_limb_t den = b_ptr[0];
  521.         mp_limb_t remainder = 0;
  522.         const mp_limb_t *sourceptr = a_ptr + a_len;
  523.         mp_limb_t *destptr = q_ptr + a_len;
  524.         size_t count;
  525.         for (count = a_len; count > 0; count--)
  526.           {
  527.             mp_twolimb_t num =
  528.               ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--sourceptr;
  529.             *--destptr = num / den;
  530.             remainder = num % den;
  531.           }
  532.         /* Normalise and store r.  */
  533.         if (remainder > 0)
  534.           {
  535.             r_ptr[0] = remainder;
  536.             r_len = 1;
  537.           }
  538.         else
  539.           r_len = 0;
  540.         /* Normalise q.  */
  541.         q_len = a_len;
  542.         if (q_ptr[q_len - 1] == 0)
  543.           q_len--;
  544.       }
  545.     }
  546.   else
  547.     {
  548.       /* n>1: multiple precision division.
  549.          beta^(m-1) <= a < beta^m, beta^(n-1) <= b < beta^n  ==>
  550.          beta^(m-n-1) <= a/b < beta^(m-n+1).  */
  551.       /* Determine s.  */
  552.       size_t s;
  553.       {
  554.         mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */
  555.         s = 31;
  556.         if (msd >= 0x10000)
  557.           {
  558.             msd = msd >> 16;
  559.             s -= 16;
  560.           }
  561.         if (msd >= 0x100)
  562.           {
  563.             msd = msd >> 8;
  564.             s -= 8;
  565.           }
  566.         if (msd >= 0x10)
  567.           {
  568.             msd = msd >> 4;
  569.             s -= 4;
  570.           }
  571.         if (msd >= 0x4)
  572.           {
  573.             msd = msd >> 2;
  574.             s -= 2;
  575.           }
  576.         if (msd >= 0x2)
  577.           {
  578.             msd = msd >> 1;
  579.             s -= 1;
  580.           }
  581.       }
  582.       /* 0 <= s < GMP_LIMB_BITS.
  583.          Copy b, shifting it left by s bits.  */
  584.       if (s > 0)
  585.         {
  586.           tmp_roomptr = (mp_limb_t *) malloc (b_len * sizeof (mp_limb_t));
  587.           if (tmp_roomptr == NULL)
  588.             {
  589.               free (roomptr);
  590.               return NULL;
  591.             }
  592.           {
  593.             const mp_limb_t *sourceptr = b_ptr;
  594.             mp_limb_t *destptr = tmp_roomptr;
  595.             mp_twolimb_t accu = 0;
  596.             size_t count;
  597.             for (count = b_len; count > 0; count--)
  598.               {
  599.                 accu += (mp_twolimb_t) *sourceptr++ << s;
  600.                 *destptr++ = (mp_limb_t) accu;
  601.                 accu = accu >> GMP_LIMB_BITS;
  602.               }
  603.             /* accu must be zero, since that was how s was determined.  */
  604.             if (accu != 0)
  605.               abort ();
  606.           }
  607.           b_ptr = tmp_roomptr;
  608.         }
  609.       /* Copy a, shifting it left by s bits, yields r.
  610.          Memory layout:
  611.          At the beginning: r = roomptr[0..a_len],
  612.          at the end: r = roomptr[0..b_len-1], q = roomptr[b_len..a_len]  */
  613.       r_ptr = roomptr;
  614.       if (s == 0)
  615.         {
  616.           memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
  617.           r_ptr[a_len] = 0;
  618.         }
  619.       else
  620.         {
  621.           const mp_limb_t *sourceptr = a_ptr;
  622.           mp_limb_t *destptr = r_ptr;
  623.           mp_twolimb_t accu = 0;
  624.           size_t count;
  625.           for (count = a_len; count > 0; count--)
  626.             {
  627.               accu += (mp_twolimb_t) *sourceptr++ << s;
  628.               *destptr++ = (mp_limb_t) accu;
  629.               accu = accu >> GMP_LIMB_BITS;
  630.             }
  631.           *destptr++ = (mp_limb_t) accu;
  632.         }
  633.       q_ptr = roomptr + b_len;
  634.       q_len = a_len - b_len + 1; /* q will have m-n+1 limbs */
  635.       {
  636.         size_t j = a_len - b_len; /* m-n */
  637.         mp_limb_t b_msd = b_ptr[b_len - 1]; /* b[n-1] */
  638.         mp_limb_t b_2msd = b_ptr[b_len - 2]; /* b[n-2] */
  639.         mp_twolimb_t b_msdd = /* b[n-1]*beta+b[n-2] */
  640.           ((mp_twolimb_t) b_msd << GMP_LIMB_BITS) | b_2msd;
  641.         /* Division loop, traversed m-n+1 times.
  642.            j counts down, b is unchanged, beta/2 <= b[n-1] < beta.  */
  643.         for (;;)
  644.           {
  645.             mp_limb_t q_star;
  646.             mp_limb_t c1;
  647.             if (r_ptr[j + b_len] < b_msd) /* r[j+n] < b[n-1] ? */
  648.               {
  649.                 /* Divide r[j+n]*beta+r[j+n-1] by b[n-1], no overflow.  */
  650.                 mp_twolimb_t num =
  651.                   ((mp_twolimb_t) r_ptr[j + b_len] << GMP_LIMB_BITS)
  652.                   | r_ptr[j + b_len - 1];
  653.                 q_star = num / b_msd;
  654.                 c1 = num % b_msd;
  655.               }
  656.             else
  657.               {
  658.                 /* Overflow, hence r[j+n]*beta+r[j+n-1] >= beta*b[n-1].  */
  659.                 q_star = (mp_limb_t)~(mp_limb_t)0; /* q* = beta-1 */
  660.                 /* Test whether r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] >= beta
  661.                    <==> r[j+n]*beta+r[j+n-1] + b[n-1] >= beta*b[n-1]+beta
  662.                    <==> b[n-1] < floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta)
  663.                         {<= beta !}.
  664.                    If yes, jump directly to the subtraction loop.
  665.                    (Otherwise, r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] < beta
  666.                     <==> floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) = b[n-1] ) */
  667.                 if (r_ptr[j + b_len] > b_msd
  668.                     || (c1 = r_ptr[j + b_len - 1] + b_msd) < b_msd)
  669.                   /* r[j+n] >= b[n-1]+1 or
  670.                      r[j+n] = b[n-1] and the addition r[j+n-1]+b[n-1] gives a
  671.                      carry.  */
  672.                   goto subtract;
  673.               }
  674.             /* q_star = q*,
  675.                c1 = (r[j+n]*beta+r[j+n-1]) - q* * b[n-1] (>=0, <beta).  */
  676.             {
  677.               mp_twolimb_t c2 = /* c1*beta+r[j+n-2] */
  678.                 ((mp_twolimb_t) c1 << GMP_LIMB_BITS) | r_ptr[j + b_len - 2];
  679.               mp_twolimb_t c3 = /* b[n-2] * q* */
  680.                 (mp_twolimb_t) b_2msd * (mp_twolimb_t) q_star;
  681.               /* While c2 < c3, increase c2 and decrease c3.
  682.                  Consider c3-c2.  While it is > 0, decrease it by
  683.                  b[n-1]*beta+b[n-2].  Because of b[n-1]*beta+b[n-2] >= beta^2/2
  684.                  this can happen only twice.  */
  685.               if (c3 > c2)
  686.                 {
  687.                   q_star = q_star - 1; /* q* := q* - 1 */
  688.                   if (c3 - c2 > b_msdd)
  689.                     q_star = q_star - 1; /* q* := q* - 1 */
  690.                 }
  691.             }
  692.             if (q_star > 0)
  693.               subtract:
  694.               {
  695.                 /* Subtract r := r - b * q* * beta^j.  */
  696.                 mp_limb_t cr;
  697.                 {
  698.                   const mp_limb_t *sourceptr = b_ptr;
  699.                   mp_limb_t *destptr = r_ptr + j;
  700.                   mp_twolimb_t carry = 0;
  701.                   size_t count;
  702.                   for (count = b_len; count > 0; count--)
  703.                     {
  704.                       /* Here 0 <= carry <= q*.  */
  705.                       carry =
  706.                         carry
  707.                         + (mp_twolimb_t) q_star * (mp_twolimb_t) *sourceptr++
  708.                         + (mp_limb_t) ~(*destptr);
  709.                       /* Here 0 <= carry <= beta*q* + beta-1.  */
  710.                       *destptr++ = ~(mp_limb_t) carry;
  711.                       carry = carry >> GMP_LIMB_BITS; /* <= q* */
  712.                     }
  713.                   cr = (mp_limb_t) carry;
  714.                 }
  715.                 /* Subtract cr from r_ptr[j + b_len], then forget about
  716.                    r_ptr[j + b_len].  */
  717.                 if (cr > r_ptr[j + b_len])
  718.                   {
  719.                     /* Subtraction gave a carry.  */
  720.                     q_star = q_star - 1; /* q* := q* - 1 */
  721.                     /* Add b back.  */
  722.                     {
  723.                       const mp_limb_t *sourceptr = b_ptr;
  724.                       mp_limb_t *destptr = r_ptr + j;
  725.                       mp_limb_t carry = 0;
  726.                       size_t count;
  727.                       for (count = b_len; count > 0; count--)
  728.                         {
  729.                           mp_limb_t source1 = *sourceptr++;
  730.                           mp_limb_t source2 = *destptr;
  731.                           *destptr++ = source1 + source2 + carry;
  732.                           carry =
  733.                             (carry
  734.                              ? source1 >= (mp_limb_t) ~source2
  735.                              : source1 > (mp_limb_t) ~source2);
  736.                         }
  737.                     }
  738.                     /* Forget about the carry and about r[j+n].  */
  739.                   }
  740.               }
  741.             /* q* is determined.  Store it as q[j].  */
  742.             q_ptr[j] = q_star;
  743.             if (j == 0)
  744.               break;
  745.             j--;
  746.           }
  747.       }
  748.       r_len = b_len;
  749.       /* Normalise q.  */
  750.       if (q_ptr[q_len - 1] == 0)
  751.         q_len--;
  752. # if 0 /* Not needed here, since we need r only to compare it with b/2, and
  753.           b is shifted left by s bits.  */
  754.       /* Shift r right by s bits.  */
  755.       if (s > 0)
  756.         {
  757.           mp_limb_t ptr = r_ptr + r_len;
  758.           mp_twolimb_t accu = 0;
  759.           size_t count;
  760.           for (count = r_len; count > 0; count--)
  761.             {
  762.               accu = (mp_twolimb_t) (mp_limb_t) accu << GMP_LIMB_BITS;
  763.               accu += (mp_twolimb_t) *--ptr << (GMP_LIMB_BITS - s);
  764.               *ptr = (mp_limb_t) (accu >> GMP_LIMB_BITS);
  765.             }
  766.         }
  767. # endif
  768.       /* Normalise r.  */
  769.       while (r_len > 0 && r_ptr[r_len - 1] == 0)
  770.         r_len--;
  771.     }
  772.   /* Compare r << 1 with b.  */
  773.   if (r_len > b_len)
  774.     goto increment_q;
  775.   {
  776.     size_t i;
  777.     for (i = b_len;;)
  778.       {
  779.         mp_limb_t r_i =
  780.           (i <= r_len && i > 0 ? r_ptr[i - 1] >> (GMP_LIMB_BITS - 1) : 0)
  781.           | (i < r_len ? r_ptr[i] << 1 : 0);
  782.         mp_limb_t b_i = (i < b_len ? b_ptr[i] : 0);
  783.         if (r_i > b_i)
  784.           goto increment_q;
  785.         if (r_i < b_i)
  786.           goto keep_q;
  787.         if (i == 0)
  788.           break;
  789.         i--;
  790.       }
  791.   }
  792.   if (q_len > 0 && ((q_ptr[0] & 1) != 0))
  793.     /* q is odd.  */
  794.     increment_q:
  795.     {
  796.       size_t i;
  797.       for (i = 0; i < q_len; i++)
  798.         if (++(q_ptr[i]) != 0)
  799.           goto keep_q;
  800.       q_ptr[q_len++] = 1;
  801.     }
  802.   keep_q:
  803.   if (tmp_roomptr != NULL)
  804.     free (tmp_roomptr);
  805.   q->limbs = q_ptr;
  806.   q->nlimbs = q_len;
  807.   return roomptr;
  808. }
  809.  
  810. /* Convert a bignum a >= 0, multiplied with 10^extra_zeroes, to decimal
  811.    representation.
  812.    Destroys the contents of a.
  813.    Return the allocated memory - containing the decimal digits in low-to-high
  814.    order, terminated with a NUL character - in case of success, NULL in case
  815.    of memory allocation failure.  */
  816. static char *
  817. convert_to_decimal (mpn_t a, size_t extra_zeroes)
  818. {
  819.   mp_limb_t *a_ptr = a.limbs;
  820.   size_t a_len = a.nlimbs;
  821.   /* 0.03345 is slightly larger than log(2)/(9*log(10)).  */
  822.   size_t c_len = 9 * ((size_t)(a_len * (GMP_LIMB_BITS * 0.03345f)) + 1);
  823.   char *c_ptr = (char *) malloc (xsum (c_len, extra_zeroes));
  824.   if (c_ptr != NULL)
  825.     {
  826.       char *d_ptr = c_ptr;
  827.       for (; extra_zeroes > 0; extra_zeroes--)
  828.         *d_ptr++ = '0';
  829.       while (a_len > 0)
  830.         {
  831.           /* Divide a by 10^9, in-place.  */
  832.           mp_limb_t remainder = 0;
  833.           mp_limb_t *ptr = a_ptr + a_len;
  834.           size_t count;
  835.           for (count = a_len; count > 0; count--)
  836.             {
  837.               mp_twolimb_t num =
  838.                 ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--ptr;
  839.               *ptr = num / 1000000000;
  840.               remainder = num % 1000000000;
  841.             }
  842.           /* Store the remainder as 9 decimal digits.  */
  843.           for (count = 9; count > 0; count--)
  844.             {
  845.               *d_ptr++ = '0' + (remainder % 10);
  846.               remainder = remainder / 10;
  847.             }
  848.           /* Normalize a.  */
  849.           if (a_ptr[a_len - 1] == 0)
  850.             a_len--;
  851.         }
  852.       /* Remove leading zeroes.  */
  853.       while (d_ptr > c_ptr && d_ptr[-1] == '0')
  854.         d_ptr--;
  855.       /* But keep at least one zero.  */
  856.       if (d_ptr == c_ptr)
  857.         *d_ptr++ = '0';
  858.       /* Terminate the string.  */
  859.       *d_ptr = '\0';
  860.     }
  861.   return c_ptr;
  862. }
  863.  
  864. # if NEED_PRINTF_LONG_DOUBLE
  865.  
  866. /* Assuming x is finite and >= 0:
  867.    write x as x = 2^e * m, where m is a bignum.
  868.    Return the allocated memory in case of success, NULL in case of memory
  869.    allocation failure.  */
  870. static void *
  871. decode_long_double (long double x, int *ep, mpn_t *mp)
  872. {
  873.   mpn_t m;
  874.   int exp;
  875.   long double y;
  876.   size_t i;
  877.  
  878.   /* Allocate memory for result.  */
  879.   m.nlimbs = (LDBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
  880.   m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
  881.   if (m.limbs == NULL)
  882.     return NULL;
  883.   /* Split into exponential part and mantissa.  */
  884.   y = frexpl (x, &exp);
  885.   if (!(y >= 0.0L && y < 1.0L))
  886.     abort ();
  887.   /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * LDBL_MANT_BIT), and the
  888.      latter is an integer.  */
  889.   /* Convert the mantissa (y * LDBL_MANT_BIT) to a sequence of limbs.
  890.      I'm not sure whether it's safe to cast a 'long double' value between
  891.      2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
  892.      'long double' values between 0 and 2^16 (to 'unsigned int' or 'int',
  893.      doesn't matter).  */
  894. #  if (LDBL_MANT_BIT % GMP_LIMB_BITS) != 0
  895. #   if (LDBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
  896.     {
  897.       mp_limb_t hi, lo;
  898.       y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % (GMP_LIMB_BITS / 2));
  899.       hi = (int) y;
  900.       y -= hi;
  901.       if (!(y >= 0.0L && y < 1.0L))
  902.         abort ();
  903.       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
  904.       lo = (int) y;
  905.       y -= lo;
  906.       if (!(y >= 0.0L && y < 1.0L))
  907.         abort ();
  908.       m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
  909.     }
  910. #   else
  911.     {
  912.       mp_limb_t d;
  913.       y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % GMP_LIMB_BITS);
  914.       d = (int) y;
  915.       y -= d;
  916.       if (!(y >= 0.0L && y < 1.0L))
  917.         abort ();
  918.       m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = d;
  919.     }
  920. #   endif
  921. #  endif
  922.   for (i = LDBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
  923.     {
  924.       mp_limb_t hi, lo;
  925.       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
  926.       hi = (int) y;
  927.       y -= hi;
  928.       if (!(y >= 0.0L && y < 1.0L))
  929.         abort ();
  930.       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
  931.       lo = (int) y;
  932.       y -= lo;
  933.       if (!(y >= 0.0L && y < 1.0L))
  934.         abort ();
  935.       m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
  936.     }
  937. #if 0 /* On FreeBSD 6.1/x86, 'long double' numbers sometimes have excess
  938.          precision.  */
  939.   if (!(y == 0.0L))
  940.     abort ();
  941. #endif
  942.   /* Normalise.  */
  943.   while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
  944.     m.nlimbs--;
  945.   *mp = m;
  946.   *ep = exp - LDBL_MANT_BIT;
  947.   return m.limbs;
  948. }
  949.  
  950. # endif
  951.  
  952. # if NEED_PRINTF_DOUBLE
  953.  
  954. /* Assuming x is finite and >= 0:
  955.    write x as x = 2^e * m, where m is a bignum.
  956.    Return the allocated memory in case of success, NULL in case of memory
  957.    allocation failure.  */
  958. static void *
  959. decode_double (double x, int *ep, mpn_t *mp)
  960. {
  961.   mpn_t m;
  962.   int exp;
  963.   double y;
  964.   size_t i;
  965.  
  966.   /* Allocate memory for result.  */
  967.   m.nlimbs = (DBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
  968.   m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
  969.   if (m.limbs == NULL)
  970.     return NULL;
  971.   /* Split into exponential part and mantissa.  */
  972.   y = frexp (x, &exp);
  973.   if (!(y >= 0.0 && y < 1.0))
  974.     abort ();
  975.   /* x = 2^exp * y = 2^(exp - DBL_MANT_BIT) * (y * DBL_MANT_BIT), and the
  976.      latter is an integer.  */
  977.   /* Convert the mantissa (y * DBL_MANT_BIT) to a sequence of limbs.
  978.      I'm not sure whether it's safe to cast a 'double' value between
  979.      2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
  980.      'double' values between 0 and 2^16 (to 'unsigned int' or 'int',
  981.      doesn't matter).  */
  982. #  if (DBL_MANT_BIT % GMP_LIMB_BITS) != 0
  983. #   if (DBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
  984.     {
  985.       mp_limb_t hi, lo;
  986.       y *= (mp_limb_t) 1 << (DBL_MANT_BIT % (GMP_LIMB_BITS / 2));
  987.       hi = (int) y;
  988.       y -= hi;
  989.       if (!(y >= 0.0 && y < 1.0))
  990.         abort ();
  991.       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
  992.       lo = (int) y;
  993.       y -= lo;
  994.       if (!(y >= 0.0 && y < 1.0))
  995.         abort ();
  996.       m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
  997.     }
  998. #   else
  999.     {
  1000.       mp_limb_t d;
  1001.       y *= (mp_limb_t) 1 << (DBL_MANT_BIT % GMP_LIMB_BITS);
  1002.       d = (int) y;
  1003.       y -= d;
  1004.       if (!(y >= 0.0 && y < 1.0))
  1005.         abort ();
  1006.       m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = d;
  1007.     }
  1008. #   endif
  1009. #  endif
  1010.   for (i = DBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
  1011.     {
  1012.       mp_limb_t hi, lo;
  1013.       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
  1014.       hi = (int) y;
  1015.       y -= hi;
  1016.       if (!(y >= 0.0 && y < 1.0))
  1017.         abort ();
  1018.       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
  1019.       lo = (int) y;
  1020.       y -= lo;
  1021.       if (!(y >= 0.0 && y < 1.0))
  1022.         abort ();
  1023.       m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
  1024.     }
  1025.   if (!(y == 0.0))
  1026.     abort ();
  1027.   /* Normalise.  */
  1028.   while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
  1029.     m.nlimbs--;
  1030.   *mp = m;
  1031.   *ep = exp - DBL_MANT_BIT;
  1032.   return m.limbs;
  1033. }
  1034.  
  1035. # endif
  1036.  
  1037. /* Assuming x = 2^e * m is finite and >= 0, and n is an integer:
  1038.    Returns the decimal representation of round (x * 10^n).
  1039.    Return the allocated memory - containing the decimal digits in low-to-high
  1040.    order, terminated with a NUL character - in case of success, NULL in case
  1041.    of memory allocation failure.  */
  1042. static char *
  1043. scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n)
  1044. {
  1045.   int s;
  1046.   size_t extra_zeroes;
  1047.   unsigned int abs_n;
  1048.   unsigned int abs_s;
  1049.   mp_limb_t *pow5_ptr;
  1050.   size_t pow5_len;
  1051.   unsigned int s_limbs;
  1052.   unsigned int s_bits;
  1053.   mpn_t pow5;
  1054.   mpn_t z;
  1055.   void *z_memory;
  1056.   char *digits;
  1057.  
  1058.   if (memory == NULL)
  1059.     return NULL;
  1060.   /* x = 2^e * m, hence
  1061.      y = round (2^e * 10^n * m) = round (2^(e+n) * 5^n * m)
  1062.        = round (2^s * 5^n * m).  */
  1063.   s = e + n;
  1064.   extra_zeroes = 0;
  1065.   /* Factor out a common power of 10 if possible.  */
  1066.   if (s > 0 && n > 0)
  1067.     {
  1068.       extra_zeroes = (s < n ? s : n);
  1069.       s -= extra_zeroes;
  1070.       n -= extra_zeroes;
  1071.     }
  1072.   /* Here y = round (2^s * 5^n * m) * 10^extra_zeroes.
  1073.      Before converting to decimal, we need to compute
  1074.      z = round (2^s * 5^n * m).  */
  1075.   /* Compute 5^|n|, possibly shifted by |s| bits if n and s have the same
  1076.      sign.  2.322 is slightly larger than log(5)/log(2).  */
  1077.   abs_n = (n >= 0 ? n : -n);
  1078.   abs_s = (s >= 0 ? s : -s);
  1079.   pow5_ptr = (mp_limb_t *) malloc (((int)(abs_n * (2.322f / GMP_LIMB_BITS)) + 1
  1080.                                     + abs_s / GMP_LIMB_BITS + 1)
  1081.                                    * sizeof (mp_limb_t));
  1082.   if (pow5_ptr == NULL)
  1083.     {
  1084.       free (memory);
  1085.       return NULL;
  1086.     }
  1087.   /* Initialize with 1.  */
  1088.   pow5_ptr[0] = 1;
  1089.   pow5_len = 1;
  1090.   /* Multiply with 5^|n|.  */
  1091.   if (abs_n > 0)
  1092.     {
  1093.       static mp_limb_t const small_pow5[13 + 1] =
  1094.         {
  1095.           1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625,
  1096.           48828125, 244140625, 1220703125
  1097.         };
  1098.       unsigned int n13;
  1099.       for (n13 = 0; n13 <= abs_n; n13 += 13)
  1100.         {
  1101.           mp_limb_t digit1 = small_pow5[n13 + 13 <= abs_n ? 13 : abs_n - n13];
  1102.           size_t j;
  1103.           mp_twolimb_t carry = 0;
  1104.           for (j = 0; j < pow5_len; j++)
  1105.             {
  1106.               mp_limb_t digit2 = pow5_ptr[j];
  1107.               carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
  1108.               pow5_ptr[j] = (mp_limb_t) carry;
  1109.               carry = carry >> GMP_LIMB_BITS;
  1110.             }
  1111.           if (carry > 0)
  1112.             pow5_ptr[pow5_len++] = (mp_limb_t) carry;
  1113.         }
  1114.     }
  1115.   s_limbs = abs_s / GMP_LIMB_BITS;
  1116.   s_bits = abs_s % GMP_LIMB_BITS;
  1117.   if (n >= 0 ? s >= 0 : s <= 0)
  1118.     {
  1119.       /* Multiply with 2^|s|.  */
  1120.       if (s_bits > 0)
  1121.         {
  1122.           mp_limb_t *ptr = pow5_ptr;
  1123.           mp_twolimb_t accu = 0;
  1124.           size_t count;
  1125.           for (count = pow5_len; count > 0; count--)
  1126.             {
  1127.               accu += (mp_twolimb_t) *ptr << s_bits;
  1128.               *ptr++ = (mp_limb_t) accu;
  1129.               accu = accu >> GMP_LIMB_BITS;
  1130.             }
  1131.           if (accu > 0)
  1132.             {
  1133.               *ptr = (mp_limb_t) accu;
  1134.               pow5_len++;
  1135.             }
  1136.         }
  1137.       if (s_limbs > 0)
  1138.         {
  1139.           size_t count;
  1140.           for (count = pow5_len; count > 0;)
  1141.             {
  1142.               count--;
  1143.               pow5_ptr[s_limbs + count] = pow5_ptr[count];
  1144.             }
  1145.           for (count = s_limbs; count > 0;)
  1146.             {
  1147.               count--;
  1148.               pow5_ptr[count] = 0;
  1149.             }
  1150.           pow5_len += s_limbs;
  1151.         }
  1152.       pow5.limbs = pow5_ptr;
  1153.       pow5.nlimbs = pow5_len;
  1154.       if (n >= 0)
  1155.         {
  1156.           /* Multiply m with pow5.  No division needed.  */
  1157.           z_memory = multiply (m, pow5, &z);
  1158.         }
  1159.       else
  1160.         {
  1161.           /* Divide m by pow5 and round.  */
  1162.           z_memory = divide (m, pow5, &z);
  1163.         }
  1164.     }
  1165.   else
  1166.     {
  1167.       pow5.limbs = pow5_ptr;
  1168.       pow5.nlimbs = pow5_len;
  1169.       if (n >= 0)
  1170.         {
  1171.           /* n >= 0, s < 0.
  1172.              Multiply m with pow5, then divide by 2^|s|.  */
  1173.           mpn_t numerator;
  1174.           mpn_t denominator;
  1175.           void *tmp_memory;
  1176.           tmp_memory = multiply (m, pow5, &numerator);
  1177.           if (tmp_memory == NULL)
  1178.             {
  1179.               free (pow5_ptr);
  1180.               free (memory);
  1181.               return NULL;
  1182.             }
  1183.           /* Construct 2^|s|.  */
  1184.           {
  1185.             mp_limb_t *ptr = pow5_ptr + pow5_len;
  1186.             size_t i;
  1187.             for (i = 0; i < s_limbs; i++)
  1188.               ptr[i] = 0;
  1189.             ptr[s_limbs] = (mp_limb_t) 1 << s_bits;
  1190.             denominator.limbs = ptr;
  1191.             denominator.nlimbs = s_limbs + 1;
  1192.           }
  1193.           z_memory = divide (numerator, denominator, &z);
  1194.           free (tmp_memory);
  1195.         }
  1196.       else
  1197.         {
  1198.           /* n < 0, s > 0.
  1199.              Multiply m with 2^s, then divide by pow5.  */
  1200.           mpn_t numerator;
  1201.           mp_limb_t *num_ptr;
  1202.           num_ptr = (mp_limb_t *) malloc ((m.nlimbs + s_limbs + 1)
  1203.                                           * sizeof (mp_limb_t));
  1204.           if (num_ptr == NULL)
  1205.             {
  1206.               free (pow5_ptr);
  1207.               free (memory);
  1208.               return NULL;
  1209.             }
  1210.           {
  1211.             mp_limb_t *destptr = num_ptr;
  1212.             {
  1213.               size_t i;
  1214.               for (i = 0; i < s_limbs; i++)
  1215.                 *destptr++ = 0;
  1216.             }
  1217.             if (s_bits > 0)
  1218.               {
  1219.                 const mp_limb_t *sourceptr = m.limbs;
  1220.                 mp_twolimb_t accu = 0;
  1221.                 size_t count;
  1222.                 for (count = m.nlimbs; count > 0; count--)
  1223.                   {
  1224.                     accu += (mp_twolimb_t) *sourceptr++ << s_bits;
  1225.                     *destptr++ = (mp_limb_t) accu;
  1226.                     accu = accu >> GMP_LIMB_BITS;
  1227.                   }
  1228.                 if (accu > 0)
  1229.                   *destptr++ = (mp_limb_t) accu;
  1230.               }
  1231.             else
  1232.               {
  1233.                 const mp_limb_t *sourceptr = m.limbs;
  1234.                 size_t count;
  1235.                 for (count = m.nlimbs; count > 0; count--)
  1236.                   *destptr++ = *sourceptr++;
  1237.               }
  1238.             numerator.limbs = num_ptr;
  1239.             numerator.nlimbs = destptr - num_ptr;
  1240.           }
  1241.           z_memory = divide (numerator, pow5, &z);
  1242.           free (num_ptr);
  1243.         }
  1244.     }
  1245.   free (pow5_ptr);
  1246.   free (memory);
  1247.  
  1248.   /* Here y = round (x * 10^n) = z * 10^extra_zeroes.  */
  1249.  
  1250.   if (z_memory == NULL)
  1251.     return NULL;
  1252.   digits = convert_to_decimal (z, extra_zeroes);
  1253.   free (z_memory);
  1254.   return digits;
  1255. }
  1256.  
  1257. # if NEED_PRINTF_LONG_DOUBLE
  1258.  
  1259. /* Assuming x is finite and >= 0, and n is an integer:
  1260.    Returns the decimal representation of round (x * 10^n).
  1261.    Return the allocated memory - containing the decimal digits in low-to-high
  1262.    order, terminated with a NUL character - in case of success, NULL in case
  1263.    of memory allocation failure.  */
  1264. static char *
  1265. scale10_round_decimal_long_double (long double x, int n)
  1266. {
  1267.   int e IF_LINT(= 0);
  1268.   mpn_t m;
  1269.   void *memory = decode_long_double (x, &e, &m);
  1270.   return scale10_round_decimal_decoded (e, m, memory, n);
  1271. }
  1272.  
  1273. # endif
  1274.  
  1275. # if NEED_PRINTF_DOUBLE
  1276.  
  1277. /* Assuming x is finite and >= 0, and n is an integer:
  1278.    Returns the decimal representation of round (x * 10^n).
  1279.    Return the allocated memory - containing the decimal digits in low-to-high
  1280.    order, terminated with a NUL character - in case of success, NULL in case
  1281.    of memory allocation failure.  */
  1282. static char *
  1283. scale10_round_decimal_double (double x, int n)
  1284. {
  1285.   int e IF_LINT(= 0);
  1286.   mpn_t m;
  1287.   void *memory = decode_double (x, &e, &m);
  1288.   return scale10_round_decimal_decoded (e, m, memory, n);
  1289. }
  1290.  
  1291. # endif
  1292.  
  1293. # if NEED_PRINTF_LONG_DOUBLE
  1294.  
  1295. /* Assuming x is finite and > 0:
  1296.    Return an approximation for n with 10^n <= x < 10^(n+1).
  1297.    The approximation is usually the right n, but may be off by 1 sometimes.  */
  1298. static int
  1299. floorlog10l (long double x)
  1300. {
  1301.   int exp;
  1302.   long double y;
  1303.   double z;
  1304.   double l;
  1305.  
  1306.   /* Split into exponential part and mantissa.  */
  1307.   y = frexpl (x, &exp);
  1308.   if (!(y >= 0.0L && y < 1.0L))
  1309.     abort ();
  1310.   if (y == 0.0L)
  1311.     return INT_MIN;
  1312.   if (y < 0.5L)
  1313.     {
  1314.       while (y < (1.0L / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
  1315.         {
  1316.           y *= 1.0L * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
  1317.           exp -= GMP_LIMB_BITS;
  1318.         }
  1319.       if (y < (1.0L / (1 << 16)))
  1320.         {
  1321.           y *= 1.0L * (1 << 16);
  1322.           exp -= 16;
  1323.         }
  1324.       if (y < (1.0L / (1 << 8)))
  1325.         {
  1326.           y *= 1.0L * (1 << 8);
  1327.           exp -= 8;
  1328.         }
  1329.       if (y < (1.0L / (1 << 4)))
  1330.         {
  1331.           y *= 1.0L * (1 << 4);
  1332.           exp -= 4;
  1333.         }
  1334.       if (y < (1.0L / (1 << 2)))
  1335.         {
  1336.           y *= 1.0L * (1 << 2);
  1337.           exp -= 2;
  1338.         }
  1339.       if (y < (1.0L / (1 << 1)))
  1340.         {
  1341.           y *= 1.0L * (1 << 1);
  1342.           exp -= 1;
  1343.         }
  1344.     }
  1345.   if (!(y >= 0.5L && y < 1.0L))
  1346.     abort ();
  1347.   /* Compute an approximation for l = log2(x) = exp + log2(y).  */
  1348.   l = exp;
  1349.   z = y;
  1350.   if (z < 0.70710678118654752444)
  1351.     {
  1352.       z *= 1.4142135623730950488;
  1353.       l -= 0.5;
  1354.     }
  1355.   if (z < 0.8408964152537145431)
  1356.     {
  1357.       z *= 1.1892071150027210667;
  1358.       l -= 0.25;
  1359.     }
  1360.   if (z < 0.91700404320467123175)
  1361.     {
  1362.       z *= 1.0905077326652576592;
  1363.       l -= 0.125;
  1364.     }
  1365.   if (z < 0.9576032806985736469)
  1366.     {
  1367.       z *= 1.0442737824274138403;
  1368.       l -= 0.0625;
  1369.     }
  1370.   /* Now 0.95 <= z <= 1.01.  */
  1371.   z = 1 - z;
  1372.   /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
  1373.      Four terms are enough to get an approximation with error < 10^-7.  */
  1374.   l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
  1375.   /* Finally multiply with log(2)/log(10), yields an approximation for
  1376.      log10(x).  */
  1377.   l *= 0.30102999566398119523;
  1378.   /* Round down to the next integer.  */
  1379.   return (int) l + (l < 0 ? -1 : 0);
  1380. }
  1381.  
  1382. # endif
  1383.  
  1384. # if NEED_PRINTF_DOUBLE
  1385.  
  1386. /* Assuming x is finite and > 0:
  1387.    Return an approximation for n with 10^n <= x < 10^(n+1).
  1388.    The approximation is usually the right n, but may be off by 1 sometimes.  */
  1389. static int
  1390. floorlog10 (double x)
  1391. {
  1392.   int exp;
  1393.   double y;
  1394.   double z;
  1395.   double l;
  1396.  
  1397.   /* Split into exponential part and mantissa.  */
  1398.   y = frexp (x, &exp);
  1399.   if (!(y >= 0.0 && y < 1.0))
  1400.     abort ();
  1401.   if (y == 0.0)
  1402.     return INT_MIN;
  1403.   if (y < 0.5)
  1404.     {
  1405.       while (y < (1.0 / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
  1406.         {
  1407.           y *= 1.0 * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
  1408.           exp -= GMP_LIMB_BITS;
  1409.         }
  1410.       if (y < (1.0 / (1 << 16)))
  1411.         {
  1412.           y *= 1.0 * (1 << 16);
  1413.           exp -= 16;
  1414.         }
  1415.       if (y < (1.0 / (1 << 8)))
  1416.         {
  1417.           y *= 1.0 * (1 << 8);
  1418.           exp -= 8;
  1419.         }
  1420.       if (y < (1.0 / (1 << 4)))
  1421.         {
  1422.           y *= 1.0 * (1 << 4);
  1423.           exp -= 4;
  1424.         }
  1425.       if (y < (1.0 / (1 << 2)))
  1426.         {
  1427.           y *= 1.0 * (1 << 2);
  1428.           exp -= 2;
  1429.         }
  1430.       if (y < (1.0 / (1 << 1)))
  1431.         {
  1432.           y *= 1.0 * (1 << 1);
  1433.           exp -= 1;
  1434.         }
  1435.     }
  1436.   if (!(y >= 0.5 && y < 1.0))
  1437.     abort ();
  1438.   /* Compute an approximation for l = log2(x) = exp + log2(y).  */
  1439.   l = exp;
  1440.   z = y;
  1441.   if (z < 0.70710678118654752444)
  1442.     {
  1443.       z *= 1.4142135623730950488;
  1444.       l -= 0.5;
  1445.     }
  1446.   if (z < 0.8408964152537145431)
  1447.     {
  1448.       z *= 1.1892071150027210667;
  1449.       l -= 0.25;
  1450.     }
  1451.   if (z < 0.91700404320467123175)
  1452.     {
  1453.       z *= 1.0905077326652576592;
  1454.       l -= 0.125;
  1455.     }
  1456.   if (z < 0.9576032806985736469)
  1457.     {
  1458.       z *= 1.0442737824274138403;
  1459.       l -= 0.0625;
  1460.     }
  1461.   /* Now 0.95 <= z <= 1.01.  */
  1462.   z = 1 - z;
  1463.   /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
  1464.      Four terms are enough to get an approximation with error < 10^-7.  */
  1465.   l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
  1466.   /* Finally multiply with log(2)/log(10), yields an approximation for
  1467.      log10(x).  */
  1468.   l *= 0.30102999566398119523;
  1469.   /* Round down to the next integer.  */
  1470.   return (int) l + (l < 0 ? -1 : 0);
  1471. }
  1472.  
  1473. # endif
  1474.  
  1475. /* Tests whether a string of digits consists of exactly PRECISION zeroes and
  1476.    a single '1' digit.  */
  1477. static int
  1478. is_borderline (const char *digits, size_t precision)
  1479. {
  1480.   for (; precision > 0; precision--, digits++)
  1481.     if (*digits != '0')
  1482.       return 0;
  1483.   if (*digits != '1')
  1484.     return 0;
  1485.   digits++;
  1486.   return *digits == '\0';
  1487. }
  1488.  
  1489. #endif
  1490.  
  1491. #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99
  1492.  
  1493. /* Use a different function name, to make it possible that the 'wchar_t'
  1494.    parametrization and the 'char' parametrization get compiled in the same
  1495.    translation unit.  */
  1496. # if WIDE_CHAR_VERSION
  1497. #  define MAX_ROOM_NEEDED wmax_room_needed
  1498. # else
  1499. #  define MAX_ROOM_NEEDED max_room_needed
  1500. # endif
  1501.  
  1502. /* Returns the number of TCHAR_T units needed as temporary space for the result
  1503.    of sprintf or SNPRINTF of a single conversion directive.  */
  1504. static inline size_t
  1505. MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
  1506.                  arg_type type, int flags, size_t width, int has_precision,
  1507.                  size_t precision, int pad_ourselves)
  1508. {
  1509.   size_t tmp_length;
  1510.  
  1511.   switch (conversion)
  1512.     {
  1513.     case 'd': case 'i': case 'u':
  1514. # if HAVE_LONG_LONG_INT
  1515.       if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
  1516.         tmp_length =
  1517.           (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
  1518.                           * 0.30103 /* binary -> decimal */
  1519.                          )
  1520.           + 1; /* turn floor into ceil */
  1521.       else
  1522. # endif
  1523.       if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
  1524.         tmp_length =
  1525.           (unsigned int) (sizeof (unsigned long) * CHAR_BIT
  1526.                           * 0.30103 /* binary -> decimal */
  1527.                          )
  1528.           + 1; /* turn floor into ceil */
  1529.       else
  1530.         tmp_length =
  1531.           (unsigned int) (sizeof (unsigned int) * CHAR_BIT
  1532.                           * 0.30103 /* binary -> decimal */
  1533.                          )
  1534.           + 1; /* turn floor into ceil */
  1535.       if (tmp_length < precision)
  1536.         tmp_length = precision;
  1537.       /* Multiply by 2, as an estimate for FLAG_GROUP.  */
  1538.       tmp_length = xsum (tmp_length, tmp_length);
  1539.       /* Add 1, to account for a leading sign.  */
  1540.       tmp_length = xsum (tmp_length, 1);
  1541.       break;
  1542.  
  1543.     case 'o':
  1544. # if HAVE_LONG_LONG_INT
  1545.       if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
  1546.         tmp_length =
  1547.           (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
  1548.                           * 0.333334 /* binary -> octal */
  1549.                          )
  1550.           + 1; /* turn floor into ceil */
  1551.       else
  1552. # endif
  1553.       if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
  1554.         tmp_length =
  1555.           (unsigned int) (sizeof (unsigned long) * CHAR_BIT
  1556.                           * 0.333334 /* binary -> octal */
  1557.                          )
  1558.           + 1; /* turn floor into ceil */
  1559.       else
  1560.         tmp_length =
  1561.           (unsigned int) (sizeof (unsigned int) * CHAR_BIT
  1562.                           * 0.333334 /* binary -> octal */
  1563.                          )
  1564.           + 1; /* turn floor into ceil */
  1565.       if (tmp_length < precision)
  1566.         tmp_length = precision;
  1567.       /* Add 1, to account for a leading sign.  */
  1568.       tmp_length = xsum (tmp_length, 1);
  1569.       break;
  1570.  
  1571.     case 'x': case 'X':
  1572. # if HAVE_LONG_LONG_INT
  1573.       if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
  1574.         tmp_length =
  1575.           (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
  1576.                           * 0.25 /* binary -> hexadecimal */
  1577.                          )
  1578.           + 1; /* turn floor into ceil */
  1579.       else
  1580. # endif
  1581.       if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
  1582.         tmp_length =
  1583.           (unsigned int) (sizeof (unsigned long) * CHAR_BIT
  1584.                           * 0.25 /* binary -> hexadecimal */
  1585.                          )
  1586.           + 1; /* turn floor into ceil */
  1587.       else
  1588.         tmp_length =
  1589.           (unsigned int) (sizeof (unsigned int) * CHAR_BIT
  1590.                           * 0.25 /* binary -> hexadecimal */
  1591.                          )
  1592.           + 1; /* turn floor into ceil */
  1593.       if (tmp_length < precision)
  1594.         tmp_length = precision;
  1595.       /* Add 2, to account for a leading sign or alternate form.  */
  1596.       tmp_length = xsum (tmp_length, 2);
  1597.       break;
  1598.  
  1599.     case 'f': case 'F':
  1600.       if (type == TYPE_LONGDOUBLE)
  1601.         tmp_length =
  1602.           (unsigned int) (LDBL_MAX_EXP
  1603.                           * 0.30103 /* binary -> decimal */
  1604.                           * 2 /* estimate for FLAG_GROUP */
  1605.                          )
  1606.           + 1 /* turn floor into ceil */
  1607.           + 10; /* sign, decimal point etc. */
  1608.       else
  1609.         tmp_length =
  1610.           (unsigned int) (DBL_MAX_EXP
  1611.                           * 0.30103 /* binary -> decimal */
  1612.                           * 2 /* estimate for FLAG_GROUP */
  1613.                          )
  1614.           + 1 /* turn floor into ceil */
  1615.           + 10; /* sign, decimal point etc. */
  1616.       tmp_length = xsum (tmp_length, precision);
  1617.       break;
  1618.  
  1619.     case 'e': case 'E': case 'g': case 'G':
  1620.       tmp_length =
  1621.         12; /* sign, decimal point, exponent etc. */
  1622.       tmp_length = xsum (tmp_length, precision);
  1623.       break;
  1624.  
  1625.     case 'a': case 'A':
  1626.       if (type == TYPE_LONGDOUBLE)
  1627.         tmp_length =
  1628.           (unsigned int) (LDBL_DIG
  1629.                           * 0.831 /* decimal -> hexadecimal */
  1630.                          )
  1631.           + 1; /* turn floor into ceil */
  1632.       else
  1633.         tmp_length =
  1634.           (unsigned int) (DBL_DIG
  1635.                           * 0.831 /* decimal -> hexadecimal */
  1636.                          )
  1637.           + 1; /* turn floor into ceil */
  1638.       if (tmp_length < precision)
  1639.         tmp_length = precision;
  1640.       /* Account for sign, decimal point etc. */
  1641.       tmp_length = xsum (tmp_length, 12);
  1642.       break;
  1643.  
  1644.     case 'c':
  1645. # if HAVE_WINT_T && !WIDE_CHAR_VERSION
  1646.       if (type == TYPE_WIDE_CHAR)
  1647.         tmp_length = MB_CUR_MAX;
  1648.       else
  1649. # endif
  1650.         tmp_length = 1;
  1651.       break;
  1652.  
  1653.     case 's':
  1654. # if HAVE_WCHAR_T
  1655.       if (type == TYPE_WIDE_STRING)
  1656.         {
  1657. #  if WIDE_CHAR_VERSION
  1658.           /* ISO C says about %ls in fwprintf:
  1659.                "If the precision is not specified or is greater than the size
  1660.                 of the array, the array shall contain a null wide character."
  1661.              So if there is a precision, we must not use wcslen.  */
  1662.           const wchar_t *arg = ap->arg[arg_index].a.a_wide_string;
  1663.  
  1664.           if (has_precision)
  1665.             tmp_length = local_wcsnlen (arg, precision);
  1666.           else
  1667.             tmp_length = local_wcslen (arg);
  1668. #  else
  1669.           /* ISO C says about %ls in fprintf:
  1670.                "If a precision is specified, no more than that many bytes are
  1671.                 written (including shift sequences, if any), and the array
  1672.                 shall contain a null wide character if, to equal the multibyte
  1673.                 character sequence length given by the precision, the function
  1674.                 would need to access a wide character one past the end of the
  1675.                 array."
  1676.              So if there is a precision, we must not use wcslen.  */
  1677.           /* This case has already been handled separately in VASNPRINTF.  */
  1678.           abort ();
  1679. #  endif
  1680.         }
  1681.       else
  1682. # endif
  1683.         {
  1684. # if WIDE_CHAR_VERSION
  1685.           /* ISO C says about %s in fwprintf:
  1686.                "If the precision is not specified or is greater than the size
  1687.                 of the converted array, the converted array shall contain a
  1688.                 null wide character."
  1689.              So if there is a precision, we must not use strlen.  */
  1690.           /* This case has already been handled separately in VASNPRINTF.  */
  1691.           abort ();
  1692. # else
  1693.           /* ISO C says about %s in fprintf:
  1694.                "If the precision is not specified or greater than the size of
  1695.                 the array, the array shall contain a null character."
  1696.              So if there is a precision, we must not use strlen.  */
  1697.           const char *arg = ap->arg[arg_index].a.a_string;
  1698.  
  1699.           if (has_precision)
  1700.             tmp_length = local_strnlen (arg, precision);
  1701.           else
  1702.             tmp_length = strlen (arg);
  1703. # endif
  1704.         }
  1705.       break;
  1706.  
  1707.     case 'p':
  1708.       tmp_length =
  1709.         (unsigned int) (sizeof (void *) * CHAR_BIT
  1710.                         * 0.25 /* binary -> hexadecimal */
  1711.                        )
  1712.           + 1 /* turn floor into ceil */
  1713.           + 2; /* account for leading 0x */
  1714.       break;
  1715.  
  1716.     default:
  1717.       abort ();
  1718.     }
  1719.  
  1720.   if (!pad_ourselves)
  1721.     {
  1722. # if ENABLE_UNISTDIO
  1723.       /* Padding considers the number of characters, therefore the number of
  1724.          elements after padding may be
  1725.            > max (tmp_length, width)
  1726.          but is certainly
  1727.            <= tmp_length + width.  */
  1728.       tmp_length = xsum (tmp_length, width);
  1729. # else
  1730.       /* Padding considers the number of elements, says POSIX.  */
  1731.       if (tmp_length < width)
  1732.         tmp_length = width;
  1733. # endif
  1734.     }
  1735.  
  1736.   tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
  1737.  
  1738.   return tmp_length;
  1739. }
  1740.  
  1741. #endif
  1742.  
  1743. DCHAR_T *
  1744. VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
  1745.             const FCHAR_T *format, va_list args)
  1746. {
  1747.   DIRECTIVES d;
  1748.   arguments a;
  1749.  
  1750.   if (PRINTF_PARSE (format, &d, &a) < 0)
  1751.     /* errno is already set.  */
  1752.     return NULL;
  1753.  
  1754. #define CLEANUP() \
  1755.   free (d.dir);                                                         \
  1756.   if (a.arg)                                                            \
  1757.     free (a.arg);
  1758.  
  1759.   if (PRINTF_FETCHARGS (args, &a) < 0)
  1760.     {
  1761.       CLEANUP ();
  1762.       errno = EINVAL;
  1763.       return NULL;
  1764.     }
  1765.  
  1766.   {
  1767.     size_t buf_neededlength;
  1768.     TCHAR_T *buf;
  1769.     TCHAR_T *buf_malloced;
  1770.     const FCHAR_T *cp;
  1771.     size_t i;
  1772.     DIRECTIVE *dp;
  1773.     /* Output string accumulator.  */
  1774.     DCHAR_T *result;
  1775.     size_t allocated;
  1776.     size_t length;
  1777.  
  1778.     /* Allocate a small buffer that will hold a directive passed to
  1779.        sprintf or snprintf.  */
  1780.     buf_neededlength =
  1781.       xsum4 (7, d.max_width_length, d.max_precision_length, 6);
  1782. #if HAVE_ALLOCA
  1783.     if (buf_neededlength < 4000 / sizeof (TCHAR_T))
  1784.       {
  1785.         buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T));
  1786.         buf_malloced = NULL;
  1787.       }
  1788.     else
  1789. #endif
  1790.       {
  1791.         size_t buf_memsize = xtimes (buf_neededlength, sizeof (TCHAR_T));
  1792.         if (size_overflow_p (buf_memsize))
  1793.           goto out_of_memory_1;
  1794.         buf = (TCHAR_T *) malloc (buf_memsize);
  1795.         if (buf == NULL)
  1796.           goto out_of_memory_1;
  1797.         buf_malloced = buf;
  1798.       }
  1799.  
  1800.     if (resultbuf != NULL)
  1801.       {
  1802.         result = resultbuf;
  1803.         allocated = *lengthp;
  1804.       }
  1805.     else
  1806.       {
  1807.         result = NULL;
  1808.         allocated = 0;
  1809.       }
  1810.     length = 0;
  1811.     /* Invariants:
  1812.        result is either == resultbuf or == NULL or malloc-allocated.
  1813.        If length > 0, then result != NULL.  */
  1814.  
  1815.     /* Ensures that allocated >= needed.  Aborts through a jump to
  1816.        out_of_memory if needed is SIZE_MAX or otherwise too big.  */
  1817. #define ENSURE_ALLOCATION(needed) \
  1818.     if ((needed) > allocated)                                                \
  1819.       {                                                                      \
  1820.         size_t memory_size;                                                  \
  1821.         DCHAR_T *memory;                                                     \
  1822.                                                                              \
  1823.         allocated = (allocated > 0 ? xtimes (allocated, 2) : 12);            \
  1824.         if ((needed) > allocated)                                            \
  1825.           allocated = (needed);                                              \
  1826.         memory_size = xtimes (allocated, sizeof (DCHAR_T));                  \
  1827.         if (size_overflow_p (memory_size))                                   \
  1828.           goto out_of_memory;                                                \
  1829.         if (result == resultbuf || result == NULL)                           \
  1830.           memory = (DCHAR_T *) malloc (memory_size);                         \
  1831.         else                                                                 \
  1832.           memory = (DCHAR_T *) realloc (result, memory_size);                \
  1833.         if (memory == NULL)                                                  \
  1834.           goto out_of_memory;                                                \
  1835.         if (result == resultbuf && length > 0)                               \
  1836.           DCHAR_CPY (memory, result, length);                                \
  1837.         result = memory;                                                     \
  1838.       }
  1839.  
  1840.     for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
  1841.       {
  1842.         if (cp != dp->dir_start)
  1843.           {
  1844.             size_t n = dp->dir_start - cp;
  1845.             size_t augmented_length = xsum (length, n);
  1846.  
  1847.             ENSURE_ALLOCATION (augmented_length);
  1848.             /* This copies a piece of FCHAR_T[] into a DCHAR_T[].  Here we
  1849.                need that the format string contains only ASCII characters
  1850.                if FCHAR_T and DCHAR_T are not the same type.  */
  1851.             if (sizeof (FCHAR_T) == sizeof (DCHAR_T))
  1852.               {
  1853.                 DCHAR_CPY (result + length, (const DCHAR_T *) cp, n);
  1854.                 length = augmented_length;
  1855.               }
  1856.             else
  1857.               {
  1858.                 do
  1859.                   result[length++] = (unsigned char) *cp++;
  1860.                 while (--n > 0);
  1861.               }
  1862.           }
  1863.         if (i == d.count)
  1864.           break;
  1865.  
  1866.         /* Execute a single directive.  */
  1867.         if (dp->conversion == '%')
  1868.           {
  1869.             size_t augmented_length;
  1870.  
  1871.             if (!(dp->arg_index == ARG_NONE))
  1872.               abort ();
  1873.             augmented_length = xsum (length, 1);
  1874.             ENSURE_ALLOCATION (augmented_length);
  1875.             result[length] = '%';
  1876.             length = augmented_length;
  1877.           }
  1878.         else
  1879.           {
  1880.             if (!(dp->arg_index != ARG_NONE))
  1881.               abort ();
  1882.  
  1883.             if (dp->conversion == 'n')
  1884.               {
  1885.                 switch (a.arg[dp->arg_index].type)
  1886.                   {
  1887.                   case TYPE_COUNT_SCHAR_POINTER:
  1888.                     *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
  1889.                     break;
  1890.                   case TYPE_COUNT_SHORT_POINTER:
  1891.                     *a.arg[dp->arg_index].a.a_count_short_pointer = length;
  1892.                     break;
  1893.                   case TYPE_COUNT_INT_POINTER:
  1894.                     *a.arg[dp->arg_index].a.a_count_int_pointer = length;
  1895.                     break;
  1896.                   case TYPE_COUNT_LONGINT_POINTER:
  1897.                     *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
  1898.                     break;
  1899. #if HAVE_LONG_LONG_INT
  1900.                   case TYPE_COUNT_LONGLONGINT_POINTER:
  1901.                     *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
  1902.                     break;
  1903. #endif
  1904.                   default:
  1905.                     abort ();
  1906.                   }
  1907.               }
  1908. #if ENABLE_UNISTDIO
  1909.             /* The unistdio extensions.  */
  1910.             else if (dp->conversion == 'U')
  1911.               {
  1912.                 arg_type type = a.arg[dp->arg_index].type;
  1913.                 int flags = dp->flags;
  1914.                 int has_width;
  1915.                 size_t width;
  1916.                 int has_precision;
  1917.                 size_t precision;
  1918.  
  1919.                 has_width = 0;
  1920.                 width = 0;
  1921.                 if (dp->width_start != dp->width_end)
  1922.                   {
  1923.                     if (dp->width_arg_index != ARG_NONE)
  1924.                       {
  1925.                         int arg;
  1926.  
  1927.                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
  1928.                           abort ();
  1929.                         arg = a.arg[dp->width_arg_index].a.a_int;
  1930.                         if (arg < 0)
  1931.                           {
  1932.                             /* "A negative field width is taken as a '-' flag
  1933.                                 followed by a positive field width."  */
  1934.                             flags |= FLAG_LEFT;
  1935.                             width = (unsigned int) (-arg);
  1936.                           }
  1937.                         else
  1938.                           width = arg;
  1939.                       }
  1940.                     else
  1941.                       {
  1942.                         const FCHAR_T *digitp = dp->width_start;
  1943.  
  1944.                         do
  1945.                           width = xsum (xtimes (width, 10), *digitp++ - '0');
  1946.                         while (digitp != dp->width_end);
  1947.                       }
  1948.                     has_width = 1;
  1949.                   }
  1950.  
  1951.                 has_precision = 0;
  1952.                 precision = 0;
  1953.                 if (dp->precision_start != dp->precision_end)
  1954.                   {
  1955.                     if (dp->precision_arg_index != ARG_NONE)
  1956.                       {
  1957.                         int arg;
  1958.  
  1959.                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
  1960.                           abort ();
  1961.                         arg = a.arg[dp->precision_arg_index].a.a_int;
  1962.                         /* "A negative precision is taken as if the precision
  1963.                             were omitted."  */
  1964.                         if (arg >= 0)
  1965.                           {
  1966.                             precision = arg;
  1967.                             has_precision = 1;
  1968.                           }
  1969.                       }
  1970.                     else
  1971.                       {
  1972.                         const FCHAR_T *digitp = dp->precision_start + 1;
  1973.  
  1974.                         precision = 0;
  1975.                         while (digitp != dp->precision_end)
  1976.                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
  1977.                         has_precision = 1;
  1978.                       }
  1979.                   }
  1980.  
  1981.                 switch (type)
  1982.                   {
  1983.                   case TYPE_U8_STRING:
  1984.                     {
  1985.                       const uint8_t *arg = a.arg[dp->arg_index].a.a_u8_string;
  1986.                       const uint8_t *arg_end;
  1987.                       size_t characters;
  1988.  
  1989.                       if (has_precision)
  1990.                         {
  1991.                           /* Use only PRECISION characters, from the left.  */
  1992.                           arg_end = arg;
  1993.                           characters = 0;
  1994.                           for (; precision > 0; precision--)
  1995.                             {
  1996.                               int count = u8_strmblen (arg_end);
  1997.                               if (count == 0)
  1998.                                 break;
  1999.                               if (count < 0)
  2000.                                 {
  2001.                                   if (!(result == resultbuf || result == NULL))
  2002.                                     free (result);
  2003.                                   if (buf_malloced != NULL)
  2004.                                     free (buf_malloced);
  2005.                                   CLEANUP ();
  2006.                                   errno = EILSEQ;
  2007.                                   return NULL;
  2008.                                 }
  2009.                               arg_end += count;
  2010.                               characters++;
  2011.                             }
  2012.                         }
  2013.                       else if (has_width)
  2014.                         {
  2015.                           /* Use the entire string, and count the number of
  2016.                              characters.  */
  2017.                           arg_end = arg;
  2018.                           characters = 0;
  2019.                           for (;;)
  2020.                             {
  2021.                               int count = u8_strmblen (arg_end);
  2022.                               if (count == 0)
  2023.                                 break;
  2024.                               if (count < 0)
  2025.                                 {
  2026.                                   if (!(result == resultbuf || result == NULL))
  2027.                                     free (result);
  2028.                                   if (buf_malloced != NULL)
  2029.                                     free (buf_malloced);
  2030.                                   CLEANUP ();
  2031.                                   errno = EILSEQ;
  2032.                                   return NULL;
  2033.                                 }
  2034.                               arg_end += count;
  2035.                               characters++;
  2036.                             }
  2037.                         }
  2038.                       else
  2039.                         {
  2040.                           /* Use the entire string.  */
  2041.                           arg_end = arg + u8_strlen (arg);
  2042.                           /* The number of characters doesn't matter.  */
  2043.                           characters = 0;
  2044.                         }
  2045.  
  2046.                       if (has_width && width > characters
  2047.                           && !(dp->flags & FLAG_LEFT))
  2048.                         {
  2049.                           size_t n = width - characters;
  2050.                           ENSURE_ALLOCATION (xsum (length, n));
  2051.                           DCHAR_SET (result + length, ' ', n);
  2052.                           length += n;
  2053.                         }
  2054.  
  2055. # if DCHAR_IS_UINT8_T
  2056.                       {
  2057.                         size_t n = arg_end - arg;
  2058.                         ENSURE_ALLOCATION (xsum (length, n));
  2059.                         DCHAR_CPY (result + length, arg, n);
  2060.                         length += n;
  2061.                       }
  2062. # else
  2063.                       { /* Convert.  */
  2064.                         DCHAR_T *converted = result + length;
  2065.                         size_t converted_len = allocated - length;
  2066. #  if DCHAR_IS_TCHAR
  2067.                         /* Convert from UTF-8 to locale encoding.  */
  2068.                         converted =
  2069.                           u8_conv_to_encoding (locale_charset (),
  2070.                                                iconveh_question_mark,
  2071.                                                arg, arg_end - arg, NULL,
  2072.                                                converted, &converted_len);
  2073. #  else
  2074.                         /* Convert from UTF-8 to UTF-16/UTF-32.  */
  2075.                         converted =
  2076.                           U8_TO_DCHAR (arg, arg_end - arg,
  2077.                                        converted, &converted_len);
  2078. #  endif
  2079.                         if (converted == NULL)
  2080.                           {
  2081.                             int saved_errno = errno;
  2082.                             if (!(result == resultbuf || result == NULL))
  2083.                               free (result);
  2084.                             if (buf_malloced != NULL)
  2085.                               free (buf_malloced);
  2086.                             CLEANUP ();
  2087.                             errno = saved_errno;
  2088.                             return NULL;
  2089.                           }
  2090.                         if (converted != result + length)
  2091.                           {
  2092.                             ENSURE_ALLOCATION (xsum (length, converted_len));
  2093.                             DCHAR_CPY (result + length, converted, converted_len);
  2094.                             free (converted);
  2095.                           }
  2096.                         length += converted_len;
  2097.                       }
  2098. # endif
  2099.  
  2100.                       if (has_width && width > characters
  2101.                           && (dp->flags & FLAG_LEFT))
  2102.                         {
  2103.                           size_t n = width - characters;
  2104.                           ENSURE_ALLOCATION (xsum (length, n));
  2105.                           DCHAR_SET (result + length, ' ', n);
  2106.                           length += n;
  2107.                         }
  2108.                     }
  2109.                     break;
  2110.  
  2111.                   case TYPE_U16_STRING:
  2112.                     {
  2113.                       const uint16_t *arg = a.arg[dp->arg_index].a.a_u16_string;
  2114.                       const uint16_t *arg_end;
  2115.                       size_t characters;
  2116.  
  2117.                       if (has_precision)
  2118.                         {
  2119.                           /* Use only PRECISION characters, from the left.  */
  2120.                           arg_end = arg;
  2121.                           characters = 0;
  2122.                           for (; precision > 0; precision--)
  2123.                             {
  2124.                               int count = u16_strmblen (arg_end);
  2125.                               if (count == 0)
  2126.                                 break;
  2127.                               if (count < 0)
  2128.                                 {
  2129.                                   if (!(result == resultbuf || result == NULL))
  2130.                                     free (result);
  2131.                                   if (buf_malloced != NULL)
  2132.                                     free (buf_malloced);
  2133.                                   CLEANUP ();
  2134.                                   errno = EILSEQ;
  2135.                                   return NULL;
  2136.                                 }
  2137.                               arg_end += count;
  2138.                               characters++;
  2139.                             }
  2140.                         }
  2141.                       else if (has_width)
  2142.                         {
  2143.                           /* Use the entire string, and count the number of
  2144.                              characters.  */
  2145.                           arg_end = arg;
  2146.                           characters = 0;
  2147.                           for (;;)
  2148.                             {
  2149.                               int count = u16_strmblen (arg_end);
  2150.                               if (count == 0)
  2151.                                 break;
  2152.                               if (count < 0)
  2153.                                 {
  2154.                                   if (!(result == resultbuf || result == NULL))
  2155.                                     free (result);
  2156.                                   if (buf_malloced != NULL)
  2157.                                     free (buf_malloced);
  2158.                                   CLEANUP ();
  2159.                                   errno = EILSEQ;
  2160.                                   return NULL;
  2161.                                 }
  2162.                               arg_end += count;
  2163.                               characters++;
  2164.                             }
  2165.                         }
  2166.                       else
  2167.                         {
  2168.                           /* Use the entire string.  */
  2169.                           arg_end = arg + u16_strlen (arg);
  2170.                           /* The number of characters doesn't matter.  */
  2171.                           characters = 0;
  2172.                         }
  2173.  
  2174.                       if (has_width && width > characters
  2175.                           && !(dp->flags & FLAG_LEFT))
  2176.                         {
  2177.                           size_t n = width - characters;
  2178.                           ENSURE_ALLOCATION (xsum (length, n));
  2179.                           DCHAR_SET (result + length, ' ', n);
  2180.                           length += n;
  2181.                         }
  2182.  
  2183. # if DCHAR_IS_UINT16_T
  2184.                       {
  2185.                         size_t n = arg_end - arg;
  2186.                         ENSURE_ALLOCATION (xsum (length, n));
  2187.                         DCHAR_CPY (result + length, arg, n);
  2188.                         length += n;
  2189.                       }
  2190. # else
  2191.                       { /* Convert.  */
  2192.                         DCHAR_T *converted = result + length;
  2193.                         size_t converted_len = allocated - length;
  2194. #  if DCHAR_IS_TCHAR
  2195.                         /* Convert from UTF-16 to locale encoding.  */
  2196.                         converted =
  2197.                           u16_conv_to_encoding (locale_charset (),
  2198.                                                 iconveh_question_mark,
  2199.                                                 arg, arg_end - arg, NULL,
  2200.                                                 converted, &converted_len);
  2201. #  else
  2202.                         /* Convert from UTF-16 to UTF-8/UTF-32.  */
  2203.                         converted =
  2204.                           U16_TO_DCHAR (arg, arg_end - arg,
  2205.                                         converted, &converted_len);
  2206. #  endif
  2207.                         if (converted == NULL)
  2208.                           {
  2209.                             int saved_errno = errno;
  2210.                             if (!(result == resultbuf || result == NULL))
  2211.                               free (result);
  2212.                             if (buf_malloced != NULL)
  2213.                               free (buf_malloced);
  2214.                             CLEANUP ();
  2215.                             errno = saved_errno;
  2216.                             return NULL;
  2217.                           }
  2218.                         if (converted != result + length)
  2219.                           {
  2220.                             ENSURE_ALLOCATION (xsum (length, converted_len));
  2221.                             DCHAR_CPY (result + length, converted, converted_len);
  2222.                             free (converted);
  2223.                           }
  2224.                         length += converted_len;
  2225.                       }
  2226. # endif
  2227.  
  2228.                       if (has_width && width > characters
  2229.                           && (dp->flags & FLAG_LEFT))
  2230.                         {
  2231.                           size_t n = width - characters;
  2232.                           ENSURE_ALLOCATION (xsum (length, n));
  2233.                           DCHAR_SET (result + length, ' ', n);
  2234.                           length += n;
  2235.                         }
  2236.                     }
  2237.                     break;
  2238.  
  2239.                   case TYPE_U32_STRING:
  2240.                     {
  2241.                       const uint32_t *arg = a.arg[dp->arg_index].a.a_u32_string;
  2242.                       const uint32_t *arg_end;
  2243.                       size_t characters;
  2244.  
  2245.                       if (has_precision)
  2246.                         {
  2247.                           /* Use only PRECISION characters, from the left.  */
  2248.                           arg_end = arg;
  2249.                           characters = 0;
  2250.                           for (; precision > 0; precision--)
  2251.                             {
  2252.                               int count = u32_strmblen (arg_end);
  2253.                               if (count == 0)
  2254.                                 break;
  2255.                               if (count < 0)
  2256.                                 {
  2257.                                   if (!(result == resultbuf || result == NULL))
  2258.                                     free (result);
  2259.                                   if (buf_malloced != NULL)
  2260.                                     free (buf_malloced);
  2261.                                   CLEANUP ();
  2262.                                   errno = EILSEQ;
  2263.                                   return NULL;
  2264.                                 }
  2265.                               arg_end += count;
  2266.                               characters++;
  2267.                             }
  2268.                         }
  2269.                       else if (has_width)
  2270.                         {
  2271.                           /* Use the entire string, and count the number of
  2272.                              characters.  */
  2273.                           arg_end = arg;
  2274.                           characters = 0;
  2275.                           for (;;)
  2276.                             {
  2277.                               int count = u32_strmblen (arg_end);
  2278.                               if (count == 0)
  2279.                                 break;
  2280.                               if (count < 0)
  2281.                                 {
  2282.                                   if (!(result == resultbuf || result == NULL))
  2283.                                     free (result);
  2284.                                   if (buf_malloced != NULL)
  2285.                                     free (buf_malloced);
  2286.                                   CLEANUP ();
  2287.                                   errno = EILSEQ;
  2288.                                   return NULL;
  2289.                                 }
  2290.                               arg_end += count;
  2291.                               characters++;
  2292.                             }
  2293.                         }
  2294.                       else
  2295.                         {
  2296.                           /* Use the entire string.  */
  2297.                           arg_end = arg + u32_strlen (arg);
  2298.                           /* The number of characters doesn't matter.  */
  2299.                           characters = 0;
  2300.                         }
  2301.  
  2302.                       if (has_width && width > characters
  2303.                           && !(dp->flags & FLAG_LEFT))
  2304.                         {
  2305.                           size_t n = width - characters;
  2306.                           ENSURE_ALLOCATION (xsum (length, n));
  2307.                           DCHAR_SET (result + length, ' ', n);
  2308.                           length += n;
  2309.                         }
  2310.  
  2311. # if DCHAR_IS_UINT32_T
  2312.                       {
  2313.                         size_t n = arg_end - arg;
  2314.                         ENSURE_ALLOCATION (xsum (length, n));
  2315.                         DCHAR_CPY (result + length, arg, n);
  2316.                         length += n;
  2317.                       }
  2318. # else
  2319.                       { /* Convert.  */
  2320.                         DCHAR_T *converted = result + length;
  2321.                         size_t converted_len = allocated - length;
  2322. #  if DCHAR_IS_TCHAR
  2323.                         /* Convert from UTF-32 to locale encoding.  */
  2324.                         converted =
  2325.                           u32_conv_to_encoding (locale_charset (),
  2326.                                                 iconveh_question_mark,
  2327.                                                 arg, arg_end - arg, NULL,
  2328.                                                 converted, &converted_len);
  2329. #  else
  2330.                         /* Convert from UTF-32 to UTF-8/UTF-16.  */
  2331.                         converted =
  2332.                           U32_TO_DCHAR (arg, arg_end - arg,
  2333.                                         converted, &converted_len);
  2334. #  endif
  2335.                         if (converted == NULL)
  2336.                           {
  2337.                             int saved_errno = errno;
  2338.                             if (!(result == resultbuf || result == NULL))
  2339.                               free (result);
  2340.                             if (buf_malloced != NULL)
  2341.                               free (buf_malloced);
  2342.                             CLEANUP ();
  2343.                             errno = saved_errno;
  2344.                             return NULL;
  2345.                           }
  2346.                         if (converted != result + length)
  2347.                           {
  2348.                             ENSURE_ALLOCATION (xsum (length, converted_len));
  2349.                             DCHAR_CPY (result + length, converted, converted_len);
  2350.                             free (converted);
  2351.                           }
  2352.                         length += converted_len;
  2353.                       }
  2354. # endif
  2355.  
  2356.                       if (has_width && width > characters
  2357.                           && (dp->flags & FLAG_LEFT))
  2358.                         {
  2359.                           size_t n = width - characters;
  2360.                           ENSURE_ALLOCATION (xsum (length, n));
  2361.                           DCHAR_SET (result + length, ' ', n);
  2362.                           length += n;
  2363.                         }
  2364.                     }
  2365.                     break;
  2366.  
  2367.                   default:
  2368.                     abort ();
  2369.                   }
  2370.               }
  2371. #endif
  2372. #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T
  2373.             else if (dp->conversion == 's'
  2374. # if WIDE_CHAR_VERSION
  2375.                      && a.arg[dp->arg_index].type != TYPE_WIDE_STRING
  2376. # else
  2377.                      && a.arg[dp->arg_index].type == TYPE_WIDE_STRING
  2378. # endif
  2379.                     )
  2380.               {
  2381.                 /* The normal handling of the 's' directive below requires
  2382.                    allocating a temporary buffer.  The determination of its
  2383.                    length (tmp_length), in the case when a precision is
  2384.                    specified, below requires a conversion between a char[]
  2385.                    string and a wchar_t[] wide string.  It could be done, but
  2386.                    we have no guarantee that the implementation of sprintf will
  2387.                    use the exactly same algorithm.  Without this guarantee, it
  2388.                    is possible to have buffer overrun bugs.  In order to avoid
  2389.                    such bugs, we implement the entire processing of the 's'
  2390.                    directive ourselves.  */
  2391.                 int flags = dp->flags;
  2392.                 int has_width;
  2393.                 size_t width;
  2394.                 int has_precision;
  2395.                 size_t precision;
  2396.  
  2397.                 has_width = 0;
  2398.                 width = 0;
  2399.                 if (dp->width_start != dp->width_end)
  2400.                   {
  2401.                     if (dp->width_arg_index != ARG_NONE)
  2402.                       {
  2403.                         int arg;
  2404.  
  2405.                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
  2406.                           abort ();
  2407.                         arg = a.arg[dp->width_arg_index].a.a_int;
  2408.                         if (arg < 0)
  2409.                           {
  2410.                             /* "A negative field width is taken as a '-' flag
  2411.                                 followed by a positive field width."  */
  2412.                             flags |= FLAG_LEFT;
  2413.                             width = (unsigned int) (-arg);
  2414.                           }
  2415.                         else
  2416.                           width = arg;
  2417.                       }
  2418.                     else
  2419.                       {
  2420.                         const FCHAR_T *digitp = dp->width_start;
  2421.  
  2422.                         do
  2423.                           width = xsum (xtimes (width, 10), *digitp++ - '0');
  2424.                         while (digitp != dp->width_end);
  2425.                       }
  2426.                     has_width = 1;
  2427.                   }
  2428.  
  2429.                 has_precision = 0;
  2430.                 precision = 6;
  2431.                 if (dp->precision_start != dp->precision_end)
  2432.                   {
  2433.                     if (dp->precision_arg_index != ARG_NONE)
  2434.                       {
  2435.                         int arg;
  2436.  
  2437.                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
  2438.                           abort ();
  2439.                         arg = a.arg[dp->precision_arg_index].a.a_int;
  2440.                         /* "A negative precision is taken as if the precision
  2441.                             were omitted."  */
  2442.                         if (arg >= 0)
  2443.                           {
  2444.                             precision = arg;
  2445.                             has_precision = 1;
  2446.                           }
  2447.                       }
  2448.                     else
  2449.                       {
  2450.                         const FCHAR_T *digitp = dp->precision_start + 1;
  2451.  
  2452.                         precision = 0;
  2453.                         while (digitp != dp->precision_end)
  2454.                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
  2455.                         has_precision = 1;
  2456.                       }
  2457.                   }
  2458.  
  2459. # if WIDE_CHAR_VERSION
  2460.                 /* %s in vasnwprintf.  See the specification of fwprintf.  */
  2461.                 {
  2462.                   const char *arg = a.arg[dp->arg_index].a.a_string;
  2463.                   const char *arg_end;
  2464.                   size_t characters;
  2465.  
  2466.                   if (has_precision)
  2467.                     {
  2468.                       /* Use only as many bytes as needed to produce PRECISION
  2469.                          wide characters, from the left.  */
  2470. #  if HAVE_MBRTOWC
  2471.                       mbstate_t state;
  2472.                       memset (&state, '\0', sizeof (mbstate_t));
  2473. #  endif
  2474.                       arg_end = arg;
  2475.                       characters = 0;
  2476.                       for (; precision > 0; precision--)
  2477.                         {
  2478.                           int count;
  2479. #  if HAVE_MBRTOWC
  2480.                           count = mbrlen (arg_end, MB_CUR_MAX, &state);
  2481. #  else
  2482.                           count = mblen (arg_end, MB_CUR_MAX);
  2483. #  endif
  2484.                           if (count == 0)
  2485.                             /* Found the terminating NUL.  */
  2486.                             break;
  2487.                           if (count < 0)
  2488.                             {
  2489.                               /* Invalid or incomplete multibyte character.  */
  2490.                               if (!(result == resultbuf || result == NULL))
  2491.                                 free (result);
  2492.                               if (buf_malloced != NULL)
  2493.                                 free (buf_malloced);
  2494.                               CLEANUP ();
  2495.                               errno = EILSEQ;
  2496.                               return NULL;
  2497.                             }
  2498.                           arg_end += count;
  2499.                           characters++;
  2500.                         }
  2501.                     }
  2502.                   else if (has_width)
  2503.                     {
  2504.                       /* Use the entire string, and count the number of wide
  2505.                          characters.  */
  2506. #  if HAVE_MBRTOWC
  2507.                       mbstate_t state;
  2508.                       memset (&state, '\0', sizeof (mbstate_t));
  2509. #  endif
  2510.                       arg_end = arg;
  2511.                       characters = 0;
  2512.                       for (;;)
  2513.                         {
  2514.                           int count;
  2515. #  if HAVE_MBRTOWC
  2516.                           count = mbrlen (arg_end, MB_CUR_MAX, &state);
  2517. #  else
  2518.                           count = mblen (arg_end, MB_CUR_MAX);
  2519. #  endif
  2520.                           if (count == 0)
  2521.                             /* Found the terminating NUL.  */
  2522.                             break;
  2523.                           if (count < 0)
  2524.                             {
  2525.                               /* Invalid or incomplete multibyte character.  */
  2526.                               if (!(result == resultbuf || result == NULL))
  2527.                                 free (result);
  2528.                               if (buf_malloced != NULL)
  2529.                                 free (buf_malloced);
  2530.                               CLEANUP ();
  2531.                               errno = EILSEQ;
  2532.                               return NULL;
  2533.                             }
  2534.                           arg_end += count;
  2535.                           characters++;
  2536.                         }
  2537.                     }
  2538.                   else
  2539.                     {
  2540.                       /* Use the entire string.  */
  2541.                       arg_end = arg + strlen (arg);
  2542.                       /* The number of characters doesn't matter.  */
  2543.                       characters = 0;
  2544.                     }
  2545.  
  2546.                   if (has_width && width > characters
  2547.                       && !(dp->flags & FLAG_LEFT))
  2548.                     {
  2549.                       size_t n = width - characters;
  2550.                       ENSURE_ALLOCATION (xsum (length, n));
  2551.                       DCHAR_SET (result + length, ' ', n);
  2552.                       length += n;
  2553.                     }
  2554.  
  2555.                   if (has_precision || has_width)
  2556.                     {
  2557.                       /* We know the number of wide characters in advance.  */
  2558.                       size_t remaining;
  2559. #  if HAVE_MBRTOWC
  2560.                       mbstate_t state;
  2561.                       memset (&state, '\0', sizeof (mbstate_t));
  2562. #  endif
  2563.                       ENSURE_ALLOCATION (xsum (length, characters));
  2564.                       for (remaining = characters; remaining > 0; remaining--)
  2565.                         {
  2566.                           wchar_t wc;
  2567.                           int count;
  2568. #  if HAVE_MBRTOWC
  2569.                           count = mbrtowc (&wc, arg, arg_end - arg, &state);
  2570. #  else
  2571.                           count = mbtowc (&wc, arg, arg_end - arg);
  2572. #  endif
  2573.                           if (count <= 0)
  2574.                             /* mbrtowc not consistent with mbrlen, or mbtowc
  2575.                                not consistent with mblen.  */
  2576.                             abort ();
  2577.                           result[length++] = wc;
  2578.                           arg += count;
  2579.                         }
  2580.                       if (!(arg == arg_end))
  2581.                         abort ();
  2582.                     }
  2583.                   else
  2584.                     {
  2585. #  if HAVE_MBRTOWC
  2586.                       mbstate_t state;
  2587.                       memset (&state, '\0', sizeof (mbstate_t));
  2588. #  endif
  2589.                       while (arg < arg_end)
  2590.                         {
  2591.                           wchar_t wc;
  2592.                           int count;
  2593. #  if HAVE_MBRTOWC
  2594.                           count = mbrtowc (&wc, arg, arg_end - arg, &state);
  2595. #  else
  2596.                           count = mbtowc (&wc, arg, arg_end - arg);
  2597. #  endif
  2598.                           if (count <= 0)
  2599.                             /* mbrtowc not consistent with mbrlen, or mbtowc
  2600.                                not consistent with mblen.  */
  2601.                             abort ();
  2602.                           ENSURE_ALLOCATION (xsum (length, 1));
  2603.                           result[length++] = wc;
  2604.                           arg += count;
  2605.                         }
  2606.                     }
  2607.  
  2608.                   if (has_width && width > characters
  2609.                       && (dp->flags & FLAG_LEFT))
  2610.                     {
  2611.                       size_t n = width - characters;
  2612.                       ENSURE_ALLOCATION (xsum (length, n));
  2613.                       DCHAR_SET (result + length, ' ', n);
  2614.                       length += n;
  2615.                     }
  2616.                 }
  2617. # else
  2618.                 /* %ls in vasnprintf.  See the specification of fprintf.  */
  2619.                 {
  2620.                   const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
  2621.                   const wchar_t *arg_end;
  2622.                   size_t characters;
  2623. #  if !DCHAR_IS_TCHAR
  2624.                   /* This code assumes that TCHAR_T is 'char'.  */
  2625.                   typedef int TCHAR_T_verify[2 * (sizeof (TCHAR_T) == 1) - 1];
  2626.                   TCHAR_T *tmpsrc;
  2627.                   DCHAR_T *tmpdst;
  2628.                   size_t tmpdst_len;
  2629. #  endif
  2630.                   size_t w;
  2631.  
  2632.                   if (has_precision)
  2633.                     {
  2634.                       /* Use only as many wide characters as needed to produce
  2635.                          at most PRECISION bytes, from the left.  */
  2636. #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
  2637.                       mbstate_t state;
  2638.                       memset (&state, '\0', sizeof (mbstate_t));
  2639. #  endif
  2640.                       arg_end = arg;
  2641.                       characters = 0;
  2642.                       while (precision > 0)
  2643.                         {
  2644.                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
  2645.                           int count;
  2646.  
  2647.                           if (*arg_end == 0)
  2648.                             /* Found the terminating null wide character.  */
  2649.                             break;
  2650. #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
  2651.                           count = wcrtomb (cbuf, *arg_end, &state);
  2652. #  else
  2653.                           count = wctomb (cbuf, *arg_end);
  2654. #  endif
  2655.                           if (count < 0)
  2656.                             {
  2657.                               /* Cannot convert.  */
  2658.                               if (!(result == resultbuf || result == NULL))
  2659.                                 free (result);
  2660.                               if (buf_malloced != NULL)
  2661.                                 free (buf_malloced);
  2662.                               CLEANUP ();
  2663.                               errno = EILSEQ;
  2664.                               return NULL;
  2665.                             }
  2666.                           if (precision < count)
  2667.                             break;
  2668.                           arg_end++;
  2669.                           characters += count;
  2670.                           precision -= count;
  2671.                         }
  2672.                     }
  2673. #  if DCHAR_IS_TCHAR
  2674.                   else if (has_width)
  2675. #  else
  2676.                   else
  2677. #  endif
  2678.                     {
  2679.                       /* Use the entire string, and count the number of
  2680.                          bytes.  */
  2681. #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
  2682.                       mbstate_t state;
  2683.                       memset (&state, '\0', sizeof (mbstate_t));
  2684. #  endif
  2685.                       arg_end = arg;
  2686.                       characters = 0;
  2687.                       for (;;)
  2688.                         {
  2689.                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
  2690.                           int count;
  2691.  
  2692.                           if (*arg_end == 0)
  2693.                             /* Found the terminating null wide character.  */
  2694.                             break;
  2695. #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
  2696.                           count = wcrtomb (cbuf, *arg_end, &state);
  2697. #  else
  2698.                           count = wctomb (cbuf, *arg_end);
  2699. #  endif
  2700.                           if (count < 0)
  2701.                             {
  2702.                               /* Cannot convert.  */
  2703.                               if (!(result == resultbuf || result == NULL))
  2704.                                 free (result);
  2705.                               if (buf_malloced != NULL)
  2706.                                 free (buf_malloced);
  2707.                               CLEANUP ();
  2708.                               errno = EILSEQ;
  2709.                               return NULL;
  2710.                             }
  2711.                           arg_end++;
  2712.                           characters += count;
  2713.                         }
  2714.                     }
  2715. #  if DCHAR_IS_TCHAR
  2716.                   else
  2717.                     {
  2718.                       /* Use the entire string.  */
  2719.                       arg_end = arg + local_wcslen (arg);
  2720.                       /* The number of bytes doesn't matter.  */
  2721.                       characters = 0;
  2722.                     }
  2723. #  endif
  2724.  
  2725. #  if !DCHAR_IS_TCHAR
  2726.                   /* Convert the string into a piece of temporary memory.  */
  2727.                   tmpsrc = (TCHAR_T *) malloc (characters * sizeof (TCHAR_T));
  2728.                   if (tmpsrc == NULL)
  2729.                     goto out_of_memory;
  2730.                   {
  2731.                     TCHAR_T *tmpptr = tmpsrc;
  2732.                     size_t remaining;
  2733. #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
  2734.                     mbstate_t state;
  2735.                     memset (&state, '\0', sizeof (mbstate_t));
  2736. #   endif
  2737.                     for (remaining = characters; remaining > 0; )
  2738.                       {
  2739.                         char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
  2740.                         int count;
  2741.  
  2742.                         if (*arg == 0)
  2743.                           abort ();
  2744. #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
  2745.                         count = wcrtomb (cbuf, *arg, &state);
  2746. #   else
  2747.                         count = wctomb (cbuf, *arg);
  2748. #   endif
  2749.                         if (count <= 0)
  2750.                           /* Inconsistency.  */
  2751.                           abort ();
  2752.                         memcpy (tmpptr, cbuf, count);
  2753.                         tmpptr += count;
  2754.                         arg++;
  2755.                         remaining -= count;
  2756.                       }
  2757.                     if (!(arg == arg_end))
  2758.                       abort ();
  2759.                   }
  2760.  
  2761.                   /* Convert from TCHAR_T[] to DCHAR_T[].  */
  2762.                   tmpdst =
  2763.                     DCHAR_CONV_FROM_ENCODING (locale_charset (),
  2764.                                               iconveh_question_mark,
  2765.                                               tmpsrc, characters,
  2766.                                               NULL,
  2767.                                               NULL, &tmpdst_len);
  2768.                   if (tmpdst == NULL)
  2769.                     {
  2770.                       int saved_errno = errno;
  2771.                       free (tmpsrc);
  2772.                       if (!(result == resultbuf || result == NULL))
  2773.                         free (result);
  2774.                       if (buf_malloced != NULL)
  2775.                         free (buf_malloced);
  2776.                       CLEANUP ();
  2777.                       errno = saved_errno;
  2778.                       return NULL;
  2779.                     }
  2780.                   free (tmpsrc);
  2781. #  endif
  2782.  
  2783.                   if (has_width)
  2784.                     {
  2785. #  if ENABLE_UNISTDIO
  2786.                       /* Outside POSIX, it's preferrable to compare the width
  2787.                          against the number of _characters_ of the converted
  2788.                          value.  */
  2789.                       w = DCHAR_MBSNLEN (result + length, characters);
  2790. #  else
  2791.                       /* The width is compared against the number of _bytes_
  2792.                          of the converted value, says POSIX.  */
  2793.                       w = characters;
  2794. #  endif
  2795.                     }
  2796.                   else
  2797.                     /* w doesn't matter.  */
  2798.                     w = 0;
  2799.  
  2800.                   if (has_width && width > w
  2801.                       && !(dp->flags & FLAG_LEFT))
  2802.                     {
  2803.                       size_t n = width - w;
  2804.                       ENSURE_ALLOCATION (xsum (length, n));
  2805.                       DCHAR_SET (result + length, ' ', n);
  2806.                       length += n;
  2807.                     }
  2808.  
  2809. #  if DCHAR_IS_TCHAR
  2810.                   if (has_precision || has_width)
  2811.                     {
  2812.                       /* We know the number of bytes in advance.  */
  2813.                       size_t remaining;
  2814. #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
  2815.                       mbstate_t state;
  2816.                       memset (&state, '\0', sizeof (mbstate_t));
  2817. #   endif
  2818.                       ENSURE_ALLOCATION (xsum (length, characters));
  2819.                       for (remaining = characters; remaining > 0; )
  2820.                         {
  2821.                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
  2822.                           int count;
  2823.  
  2824.                           if (*arg == 0)
  2825.                             abort ();
  2826. #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
  2827.                           count = wcrtomb (cbuf, *arg, &state);
  2828. #   else
  2829.                           count = wctomb (cbuf, *arg);
  2830. #   endif
  2831.                           if (count <= 0)
  2832.                             /* Inconsistency.  */
  2833.                             abort ();
  2834.                           memcpy (result + length, cbuf, count);
  2835.                           length += count;
  2836.                           arg++;
  2837.                           remaining -= count;
  2838.                         }
  2839.                       if (!(arg == arg_end))
  2840.                         abort ();
  2841.                     }
  2842.                   else
  2843.                     {
  2844. #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
  2845.                       mbstate_t state;
  2846.                       memset (&state, '\0', sizeof (mbstate_t));
  2847. #   endif
  2848.                       while (arg < arg_end)
  2849.                         {
  2850.                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
  2851.                           int count;
  2852.  
  2853.                           if (*arg == 0)
  2854.                             abort ();
  2855. #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
  2856.                           count = wcrtomb (cbuf, *arg, &state);
  2857. #   else
  2858.                           count = wctomb (cbuf, *arg);
  2859. #   endif
  2860.                           if (count <= 0)
  2861.                             {
  2862.                               /* Cannot convert.  */
  2863.                               if (!(result == resultbuf || result == NULL))
  2864.                                 free (result);
  2865.                               if (buf_malloced != NULL)
  2866.                                 free (buf_malloced);
  2867.                               CLEANUP ();
  2868.                               errno = EILSEQ;
  2869.                               return NULL;
  2870.                             }
  2871.                           ENSURE_ALLOCATION (xsum (length, count));
  2872.                           memcpy (result + length, cbuf, count);
  2873.                           length += count;
  2874.                           arg++;
  2875.                         }
  2876.                     }
  2877. #  else
  2878.                   ENSURE_ALLOCATION (xsum (length, tmpdst_len));
  2879.                   DCHAR_CPY (result + length, tmpdst, tmpdst_len);
  2880.                   free (tmpdst);
  2881.                   length += tmpdst_len;
  2882. #  endif
  2883.  
  2884.                   if (has_width && width > w
  2885.                       && (dp->flags & FLAG_LEFT))
  2886.                     {
  2887.                       size_t n = width - w;
  2888.                       ENSURE_ALLOCATION (xsum (length, n));
  2889.                       DCHAR_SET (result + length, ' ', n);
  2890.                       length += n;
  2891.                     }
  2892.                 }
  2893. # endif
  2894.               }
  2895. #endif
  2896. #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
  2897.             else if ((dp->conversion == 'a' || dp->conversion == 'A')
  2898. # if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE))
  2899.                      && (0
  2900. #  if NEED_PRINTF_DOUBLE
  2901.                          || a.arg[dp->arg_index].type == TYPE_DOUBLE
  2902. #  endif
  2903. #  if NEED_PRINTF_LONG_DOUBLE
  2904.                          || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
  2905. #  endif
  2906.                         )
  2907. # endif
  2908.                     )
  2909.               {
  2910.                 arg_type type = a.arg[dp->arg_index].type;
  2911.                 int flags = dp->flags;
  2912.                 int has_width;
  2913.                 size_t width;
  2914.                 int has_precision;
  2915.                 size_t precision;
  2916.                 size_t tmp_length;
  2917.                 DCHAR_T tmpbuf[700];
  2918.                 DCHAR_T *tmp;
  2919.                 DCHAR_T *pad_ptr;
  2920.                 DCHAR_T *p;
  2921.  
  2922.                 has_width = 0;
  2923.                 width = 0;
  2924.                 if (dp->width_start != dp->width_end)
  2925.                   {
  2926.                     if (dp->width_arg_index != ARG_NONE)
  2927.                       {
  2928.                         int arg;
  2929.  
  2930.                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
  2931.                           abort ();
  2932.                         arg = a.arg[dp->width_arg_index].a.a_int;
  2933.                         if (arg < 0)
  2934.                           {
  2935.                             /* "A negative field width is taken as a '-' flag
  2936.                                 followed by a positive field width."  */
  2937.                             flags |= FLAG_LEFT;
  2938.                             width = (unsigned int) (-arg);
  2939.                           }
  2940.                         else
  2941.                           width = arg;
  2942.                       }
  2943.                     else
  2944.                       {
  2945.                         const FCHAR_T *digitp = dp->width_start;
  2946.  
  2947.                         do
  2948.                           width = xsum (xtimes (width, 10), *digitp++ - '0');
  2949.                         while (digitp != dp->width_end);
  2950.                       }
  2951.                     has_width = 1;
  2952.                   }
  2953.  
  2954.                 has_precision = 0;
  2955.                 precision = 0;
  2956.                 if (dp->precision_start != dp->precision_end)
  2957.                   {
  2958.                     if (dp->precision_arg_index != ARG_NONE)
  2959.                       {
  2960.                         int arg;
  2961.  
  2962.                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
  2963.                           abort ();
  2964.                         arg = a.arg[dp->precision_arg_index].a.a_int;
  2965.                         /* "A negative precision is taken as if the precision
  2966.                             were omitted."  */
  2967.                         if (arg >= 0)
  2968.                           {
  2969.                             precision = arg;
  2970.                             has_precision = 1;
  2971.                           }
  2972.                       }
  2973.                     else
  2974.                       {
  2975.                         const FCHAR_T *digitp = dp->precision_start + 1;
  2976.  
  2977.                         precision = 0;
  2978.                         while (digitp != dp->precision_end)
  2979.                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
  2980.                         has_precision = 1;
  2981.                       }
  2982.                   }
  2983.  
  2984.                 /* Allocate a temporary buffer of sufficient size.  */
  2985.                 if (type == TYPE_LONGDOUBLE)
  2986.                   tmp_length =
  2987.                     (unsigned int) ((LDBL_DIG + 1)
  2988.                                     * 0.831 /* decimal -> hexadecimal */
  2989.                                    )
  2990.                     + 1; /* turn floor into ceil */
  2991.                 else
  2992.                   tmp_length =
  2993.                     (unsigned int) ((DBL_DIG + 1)
  2994.                                     * 0.831 /* decimal -> hexadecimal */
  2995.                                    )
  2996.                     + 1; /* turn floor into ceil */
  2997.                 if (tmp_length < precision)
  2998.                   tmp_length = precision;
  2999.                 /* Account for sign, decimal point etc. */
  3000.                 tmp_length = xsum (tmp_length, 12);
  3001.  
  3002.                 if (tmp_length < width)
  3003.                   tmp_length = width;
  3004.  
  3005.                 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
  3006.  
  3007.                 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
  3008.                   tmp = tmpbuf;
  3009.                 else
  3010.                   {
  3011.                     size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
  3012.  
  3013.                     if (size_overflow_p (tmp_memsize))
  3014.                       /* Overflow, would lead to out of memory.  */
  3015.                       goto out_of_memory;
  3016.                     tmp = (DCHAR_T *) malloc (tmp_memsize);
  3017.                     if (tmp == NULL)
  3018.                       /* Out of memory.  */
  3019.                       goto out_of_memory;
  3020.                   }
  3021.  
  3022.                 pad_ptr = NULL;
  3023.                 p = tmp;
  3024.                 if (type == TYPE_LONGDOUBLE)
  3025.                   {
  3026. # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE
  3027.                     long double arg = a.arg[dp->arg_index].a.a_longdouble;
  3028.  
  3029.                     if (isnanl (arg))
  3030.                       {
  3031.                         if (dp->conversion == 'A')
  3032.                           {
  3033.                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
  3034.                           }
  3035.                         else
  3036.                           {
  3037.                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
  3038.                           }
  3039.                       }
  3040.                     else
  3041.                       {
  3042.                         int sign = 0;
  3043.                         DECL_LONG_DOUBLE_ROUNDING
  3044.  
  3045.                         BEGIN_LONG_DOUBLE_ROUNDING ();
  3046.  
  3047.                         if (signbit (arg)) /* arg < 0.0L or negative zero */
  3048.                           {
  3049.                             sign = -1;
  3050.                             arg = -arg;
  3051.                           }
  3052.  
  3053.                         if (sign < 0)
  3054.                           *p++ = '-';
  3055.                         else if (flags & FLAG_SHOWSIGN)
  3056.                           *p++ = '+';
  3057.                         else if (flags & FLAG_SPACE)
  3058.                           *p++ = ' ';
  3059.  
  3060.                         if (arg > 0.0L && arg + arg == arg)
  3061.                           {
  3062.                             if (dp->conversion == 'A')
  3063.                               {
  3064.                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
  3065.                               }
  3066.                             else
  3067.                               {
  3068.                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
  3069.                               }
  3070.                           }
  3071.                         else
  3072.                           {
  3073.                             int exponent;
  3074.                             long double mantissa;
  3075.  
  3076.                             if (arg > 0.0L)
  3077.                               mantissa = printf_frexpl (arg, &exponent);
  3078.                             else
  3079.                               {
  3080.                                 exponent = 0;
  3081.                                 mantissa = 0.0L;
  3082.                               }
  3083.  
  3084.                             if (has_precision
  3085.                                 && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
  3086.                               {
  3087.                                 /* Round the mantissa.  */
  3088.                                 long double tail = mantissa;
  3089.                                 size_t q;
  3090.  
  3091.                                 for (q = precision; ; q--)
  3092.                                   {
  3093.                                     int digit = (int) tail;
  3094.                                     tail -= digit;
  3095.                                     if (q == 0)
  3096.                                       {
  3097.                                         if (digit & 1 ? tail >= 0.5L : tail > 0.5L)
  3098.                                           tail = 1 - tail;
  3099.                                         else
  3100.                                           tail = - tail;
  3101.                                         break;
  3102.                                       }
  3103.                                     tail *= 16.0L;
  3104.                                   }
  3105.                                 if (tail != 0.0L)
  3106.                                   for (q = precision; q > 0; q--)
  3107.                                     tail *= 0.0625L;
  3108.                                 mantissa += tail;
  3109.                               }
  3110.  
  3111.                             *p++ = '0';
  3112.                             *p++ = dp->conversion - 'A' + 'X';
  3113.                             pad_ptr = p;
  3114.                             {
  3115.                               int digit;
  3116.  
  3117.                               digit = (int) mantissa;
  3118.                               mantissa -= digit;
  3119.                               *p++ = '0' + digit;
  3120.                               if ((flags & FLAG_ALT)
  3121.                                   || mantissa > 0.0L || precision > 0)
  3122.                                 {
  3123.                                   *p++ = decimal_point_char ();
  3124.                                   /* This loop terminates because we assume
  3125.                                      that FLT_RADIX is a power of 2.  */
  3126.                                   while (mantissa > 0.0L)
  3127.                                     {
  3128.                                       mantissa *= 16.0L;
  3129.                                       digit = (int) mantissa;
  3130.                                       mantissa -= digit;
  3131.                                       *p++ = digit
  3132.                                              + (digit < 10
  3133.                                                 ? '0'
  3134.                                                 : dp->conversion - 10);
  3135.                                       if (precision > 0)
  3136.                                         precision--;
  3137.                                     }
  3138.                                   while (precision > 0)
  3139.                                     {
  3140.                                       *p++ = '0';
  3141.                                       precision--;
  3142.                                     }
  3143.                                 }
  3144.                               }
  3145.                               *p++ = dp->conversion - 'A' + 'P';
  3146. #  if WIDE_CHAR_VERSION
  3147.                               {
  3148.                                 static const wchar_t decimal_format[] =
  3149.                                   { '%', '+', 'd', '\0' };
  3150.                                 SNPRINTF (p, 6 + 1, decimal_format, exponent);
  3151.                               }
  3152.                               while (*p != '\0')
  3153.                                 p++;
  3154. #  else
  3155.                               if (sizeof (DCHAR_T) == 1)
  3156.                                 {
  3157.                                   sprintf ((char *) p, "%+d", exponent);
  3158.                                   while (*p != '\0')
  3159.                                     p++;
  3160.                                 }
  3161.                               else
  3162.                                 {
  3163.                                   char expbuf[6 + 1];
  3164.                                   const char *ep;
  3165.                                   sprintf (expbuf, "%+d", exponent);
  3166.                                   for (ep = expbuf; (*p = *ep) != '\0'; ep++)
  3167.                                     p++;
  3168.                                 }
  3169. #  endif
  3170.                           }
  3171.  
  3172.                         END_LONG_DOUBLE_ROUNDING ();
  3173.                       }
  3174. # else
  3175.                     abort ();
  3176. # endif
  3177.                   }
  3178.                 else
  3179.                   {
  3180. # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
  3181.                     double arg = a.arg[dp->arg_index].a.a_double;
  3182.  
  3183.                     if (isnand (arg))
  3184.                       {
  3185.                         if (dp->conversion == 'A')
  3186.                           {
  3187.                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
  3188.                           }
  3189.                         else
  3190.                           {
  3191.                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
  3192.                           }
  3193.                       }
  3194.                     else
  3195.                       {
  3196.                         int sign = 0;
  3197.  
  3198.                         if (signbit (arg)) /* arg < 0.0 or negative zero */
  3199.                           {
  3200.                             sign = -1;
  3201.                             arg = -arg;
  3202.                           }
  3203.  
  3204.                         if (sign < 0)
  3205.                           *p++ = '-';
  3206.                         else if (flags & FLAG_SHOWSIGN)
  3207.                           *p++ = '+';
  3208.                         else if (flags & FLAG_SPACE)
  3209.                           *p++ = ' ';
  3210.  
  3211.                         if (arg > 0.0 && arg + arg == arg)
  3212.                           {
  3213.                             if (dp->conversion == 'A')
  3214.                               {
  3215.                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
  3216.                               }
  3217.                             else
  3218.                               {
  3219.                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
  3220.                               }
  3221.                           }
  3222.                         else
  3223.                           {
  3224.                             int exponent;
  3225.                             double mantissa;
  3226.  
  3227.                             if (arg > 0.0)
  3228.                               mantissa = printf_frexp (arg, &exponent);
  3229.                             else
  3230.                               {
  3231.                                 exponent = 0;
  3232.                                 mantissa = 0.0;
  3233.                               }
  3234.  
  3235.                             if (has_precision
  3236.                                 && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
  3237.                               {
  3238.                                 /* Round the mantissa.  */
  3239.                                 double tail = mantissa;
  3240.                                 size_t q;
  3241.  
  3242.                                 for (q = precision; ; q--)
  3243.                                   {
  3244.                                     int digit = (int) tail;
  3245.                                     tail -= digit;
  3246.                                     if (q == 0)
  3247.                                       {
  3248.                                         if (digit & 1 ? tail >= 0.5 : tail > 0.5)
  3249.                                           tail = 1 - tail;
  3250.                                         else
  3251.                                           tail = - tail;
  3252.                                         break;
  3253.                                       }
  3254.                                     tail *= 16.0;
  3255.                                   }
  3256.                                 if (tail != 0.0)
  3257.                                   for (q = precision; q > 0; q--)
  3258.                                     tail *= 0.0625;
  3259.                                 mantissa += tail;
  3260.                               }
  3261.  
  3262.                             *p++ = '0';
  3263.                             *p++ = dp->conversion - 'A' + 'X';
  3264.                             pad_ptr = p;
  3265.                             {
  3266.                               int digit;
  3267.  
  3268.                               digit = (int) mantissa;
  3269.                               mantissa -= digit;
  3270.                               *p++ = '0' + digit;
  3271.                               if ((flags & FLAG_ALT)
  3272.                                   || mantissa > 0.0 || precision > 0)
  3273.                                 {
  3274.                                   *p++ = decimal_point_char ();
  3275.                                   /* This loop terminates because we assume
  3276.                                      that FLT_RADIX is a power of 2.  */
  3277.                                   while (mantissa > 0.0)
  3278.                                     {
  3279.                                       mantissa *= 16.0;
  3280.                                       digit = (int) mantissa;
  3281.                                       mantissa -= digit;
  3282.                                       *p++ = digit
  3283.                                              + (digit < 10
  3284.                                                 ? '0'
  3285.                                                 : dp->conversion - 10);
  3286.                                       if (precision > 0)
  3287.                                         precision--;
  3288.                                     }
  3289.                                   while (precision > 0)
  3290.                                     {
  3291.                                       *p++ = '0';
  3292.                                       precision--;
  3293.                                     }
  3294.                                 }
  3295.                               }
  3296.                               *p++ = dp->conversion - 'A' + 'P';
  3297. #  if WIDE_CHAR_VERSION
  3298.                               {
  3299.                                 static const wchar_t decimal_format[] =
  3300.                                   { '%', '+', 'd', '\0' };
  3301.                                 SNPRINTF (p, 6 + 1, decimal_format, exponent);
  3302.                               }
  3303.                               while (*p != '\0')
  3304.                                 p++;
  3305. #  else
  3306.                               if (sizeof (DCHAR_T) == 1)
  3307.                                 {
  3308.                                   sprintf ((char *) p, "%+d", exponent);
  3309.                                   while (*p != '\0')
  3310.                                     p++;
  3311.                                 }
  3312.                               else
  3313.                                 {
  3314.                                   char expbuf[6 + 1];
  3315.                                   const char *ep;
  3316.                                   sprintf (expbuf, "%+d", exponent);
  3317.                                   for (ep = expbuf; (*p = *ep) != '\0'; ep++)
  3318.                                     p++;
  3319.                                 }
  3320. #  endif
  3321.                           }
  3322.                       }
  3323. # else
  3324.                     abort ();
  3325. # endif
  3326.                   }
  3327.                 /* The generated string now extends from tmp to p, with the
  3328.                    zero padding insertion point being at pad_ptr.  */
  3329.                 if (has_width && p - tmp < width)
  3330.                   {
  3331.                     size_t pad = width - (p - tmp);
  3332.                     DCHAR_T *end = p + pad;
  3333.  
  3334.                     if (flags & FLAG_LEFT)
  3335.                       {
  3336.                         /* Pad with spaces on the right.  */
  3337.                         for (; pad > 0; pad--)
  3338.                           *p++ = ' ';
  3339.                       }
  3340.                     else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
  3341.                       {
  3342.                         /* Pad with zeroes.  */
  3343.                         DCHAR_T *q = end;
  3344.  
  3345.                         while (p > pad_ptr)
  3346.                           *--q = *--p;
  3347.                         for (; pad > 0; pad--)
  3348.                           *p++ = '0';
  3349.                       }
  3350.                     else
  3351.                       {
  3352.                         /* Pad with spaces on the left.  */
  3353.                         DCHAR_T *q = end;
  3354.  
  3355.                         while (p > tmp)
  3356.                           *--q = *--p;
  3357.                         for (; pad > 0; pad--)
  3358.                           *p++ = ' ';
  3359.                       }
  3360.  
  3361.                     p = end;
  3362.                   }
  3363.  
  3364.                 {
  3365.                   size_t count = p - tmp;
  3366.  
  3367.                   if (count >= tmp_length)
  3368.                     /* tmp_length was incorrectly calculated - fix the
  3369.                        code above!  */
  3370.                     abort ();
  3371.  
  3372.                   /* Make room for the result.  */
  3373.                   if (count >= allocated - length)
  3374.                     {
  3375.                       size_t n = xsum (length, count);
  3376.  
  3377.                       ENSURE_ALLOCATION (n);
  3378.                     }
  3379.  
  3380.                   /* Append the result.  */
  3381.                   memcpy (result + length, tmp, count * sizeof (DCHAR_T));
  3382.                   if (tmp != tmpbuf)
  3383.                     free (tmp);
  3384.                   length += count;
  3385.                 }
  3386.               }
  3387. #endif
  3388. #if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
  3389.             else if ((dp->conversion == 'f' || dp->conversion == 'F'
  3390.                       || dp->conversion == 'e' || dp->conversion == 'E'
  3391.                       || dp->conversion == 'g' || dp->conversion == 'G'
  3392.                       || dp->conversion == 'a' || dp->conversion == 'A')
  3393.                      && (0
  3394. # if NEED_PRINTF_DOUBLE
  3395.                          || a.arg[dp->arg_index].type == TYPE_DOUBLE
  3396. # elif NEED_PRINTF_INFINITE_DOUBLE
  3397.                          || (a.arg[dp->arg_index].type == TYPE_DOUBLE
  3398.                              /* The systems (mingw) which produce wrong output
  3399.                                 for Inf, -Inf, and NaN also do so for -0.0.
  3400.                                 Therefore we treat this case here as well.  */
  3401.                              && is_infinite_or_zero (a.arg[dp->arg_index].a.a_double))
  3402. # endif
  3403. # if NEED_PRINTF_LONG_DOUBLE
  3404.                          || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
  3405. # elif NEED_PRINTF_INFINITE_LONG_DOUBLE
  3406.                          || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
  3407.                              /* Some systems produce wrong output for Inf,
  3408.                                 -Inf, and NaN.  Some systems in this category
  3409.                                 (IRIX 5.3) also do so for -0.0.  Therefore we
  3410.                                 treat this case here as well.  */
  3411.                              && is_infinite_or_zerol (a.arg[dp->arg_index].a.a_longdouble))
  3412. # endif
  3413.                         ))
  3414.               {
  3415. # if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE)
  3416.                 arg_type type = a.arg[dp->arg_index].type;
  3417. # endif
  3418.                 int flags = dp->flags;
  3419.                 int has_width;
  3420.                 size_t width;
  3421.                 int has_precision;
  3422.                 size_t precision;
  3423.                 size_t tmp_length;
  3424.                 DCHAR_T tmpbuf[700];
  3425.                 DCHAR_T *tmp;
  3426.                 DCHAR_T *pad_ptr;
  3427.                 DCHAR_T *p;
  3428.  
  3429.                 has_width = 0;
  3430.                 width = 0;
  3431.                 if (dp->width_start != dp->width_end)
  3432.                   {
  3433.                     if (dp->width_arg_index != ARG_NONE)
  3434.                       {
  3435.                         int arg;
  3436.  
  3437.                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
  3438.                           abort ();
  3439.                         arg = a.arg[dp->width_arg_index].a.a_int;
  3440.                         if (arg < 0)
  3441.                           {
  3442.                             /* "A negative field width is taken as a '-' flag
  3443.                                 followed by a positive field width."  */
  3444.                             flags |= FLAG_LEFT;
  3445.                             width = (unsigned int) (-arg);
  3446.                           }
  3447.                         else
  3448.                           width = arg;
  3449.                       }
  3450.                     else
  3451.                       {
  3452.                         const FCHAR_T *digitp = dp->width_start;
  3453.  
  3454.                         do
  3455.                           width = xsum (xtimes (width, 10), *digitp++ - '0');
  3456.                         while (digitp != dp->width_end);
  3457.                       }
  3458.                     has_width = 1;
  3459.                   }
  3460.  
  3461.                 has_precision = 0;
  3462.                 precision = 0;
  3463.                 if (dp->precision_start != dp->precision_end)
  3464.                   {
  3465.                     if (dp->precision_arg_index != ARG_NONE)
  3466.                       {
  3467.                         int arg;
  3468.  
  3469.                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
  3470.                           abort ();
  3471.                         arg = a.arg[dp->precision_arg_index].a.a_int;
  3472.                         /* "A negative precision is taken as if the precision
  3473.                             were omitted."  */
  3474.                         if (arg >= 0)
  3475.                           {
  3476.                             precision = arg;
  3477.                             has_precision = 1;
  3478.                           }
  3479.                       }
  3480.                     else
  3481.                       {
  3482.                         const FCHAR_T *digitp = dp->precision_start + 1;
  3483.  
  3484.                         precision = 0;
  3485.                         while (digitp != dp->precision_end)
  3486.                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
  3487.                         has_precision = 1;
  3488.                       }
  3489.                   }
  3490.  
  3491.                 /* POSIX specifies the default precision to be 6 for %f, %F,
  3492.                    %e, %E, but not for %g, %G.  Implementations appear to use
  3493.                    the same default precision also for %g, %G.  But for %a, %A,
  3494.                    the default precision is 0.  */
  3495.                 if (!has_precision)
  3496.                   if (!(dp->conversion == 'a' || dp->conversion == 'A'))
  3497.                     precision = 6;
  3498.  
  3499.                 /* Allocate a temporary buffer of sufficient size.  */
  3500. # if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE
  3501.                 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG + 1);
  3502. # elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE
  3503.                 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0);
  3504. # elif NEED_PRINTF_LONG_DOUBLE
  3505.                 tmp_length = LDBL_DIG + 1;
  3506. # elif NEED_PRINTF_DOUBLE
  3507.                 tmp_length = DBL_DIG + 1;
  3508. # else
  3509.                 tmp_length = 0;
  3510. # endif
  3511.                 if (tmp_length < precision)
  3512.                   tmp_length = precision;
  3513. # if NEED_PRINTF_LONG_DOUBLE
  3514. #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
  3515.                 if (type == TYPE_LONGDOUBLE)
  3516. #  endif
  3517.                   if (dp->conversion == 'f' || dp->conversion == 'F')
  3518.                     {
  3519.                       long double arg = a.arg[dp->arg_index].a.a_longdouble;
  3520.                       if (!(isnanl (arg) || arg + arg == arg))
  3521.                         {
  3522.                           /* arg is finite and nonzero.  */
  3523.                           int exponent = floorlog10l (arg < 0 ? -arg : arg);
  3524.                           if (exponent >= 0 && tmp_length < exponent + precision)
  3525.                             tmp_length = exponent + precision;
  3526.                         }
  3527.                     }
  3528. # endif
  3529. # if NEED_PRINTF_DOUBLE
  3530. #  if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
  3531.                 if (type == TYPE_DOUBLE)
  3532. #  endif
  3533.                   if (dp->conversion == 'f' || dp->conversion == 'F')
  3534.                     {
  3535.                       double arg = a.arg[dp->arg_index].a.a_double;
  3536.                       if (!(isnand (arg) || arg + arg == arg))
  3537.                         {
  3538.                           /* arg is finite and nonzero.  */
  3539.                           int exponent = floorlog10 (arg < 0 ? -arg : arg);
  3540.                           if (exponent >= 0 && tmp_length < exponent + precision)
  3541.                             tmp_length = exponent + precision;
  3542.                         }
  3543.                     }
  3544. # endif
  3545.                 /* Account for sign, decimal point etc. */
  3546.                 tmp_length = xsum (tmp_length, 12);
  3547.  
  3548.                 if (tmp_length < width)
  3549.                   tmp_length = width;
  3550.  
  3551.                 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
  3552.  
  3553.                 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
  3554.                   tmp = tmpbuf;
  3555.                 else
  3556.                   {
  3557.                     size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
  3558.  
  3559.                     if (size_overflow_p (tmp_memsize))
  3560.                       /* Overflow, would lead to out of memory.  */
  3561.                       goto out_of_memory;
  3562.                     tmp = (DCHAR_T *) malloc (tmp_memsize);
  3563.                     if (tmp == NULL)
  3564.                       /* Out of memory.  */
  3565.                       goto out_of_memory;
  3566.                   }
  3567.  
  3568.                 pad_ptr = NULL;
  3569.                 p = tmp;
  3570.  
  3571. # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
  3572. #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
  3573.                 if (type == TYPE_LONGDOUBLE)
  3574. #  endif
  3575.                   {
  3576.                     long double arg = a.arg[dp->arg_index].a.a_longdouble;
  3577.  
  3578.                     if (isnanl (arg))
  3579.                       {
  3580.                         if (dp->conversion >= 'A' && dp->conversion <= 'Z')
  3581.                           {
  3582.                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
  3583.                           }
  3584.                         else
  3585.                           {
  3586.                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
  3587.                           }
  3588.                       }
  3589.                     else
  3590.                       {
  3591.                         int sign = 0;
  3592.                         DECL_LONG_DOUBLE_ROUNDING
  3593.  
  3594.                         BEGIN_LONG_DOUBLE_ROUNDING ();
  3595.  
  3596.                         if (signbit (arg)) /* arg < 0.0L or negative zero */
  3597.                           {
  3598.                             sign = -1;
  3599.                             arg = -arg;
  3600.                           }
  3601.  
  3602.                         if (sign < 0)
  3603.                           *p++ = '-';
  3604.                         else if (flags & FLAG_SHOWSIGN)
  3605.                           *p++ = '+';
  3606.                         else if (flags & FLAG_SPACE)
  3607.                           *p++ = ' ';
  3608.  
  3609.                         if (arg > 0.0L && arg + arg == arg)
  3610.                           {
  3611.                             if (dp->conversion >= 'A' && dp->conversion <= 'Z')
  3612.                               {
  3613.                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
  3614.                               }
  3615.                             else
  3616.                               {
  3617.                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
  3618.                               }
  3619.                           }
  3620.                         else
  3621.                           {
  3622. #  if NEED_PRINTF_LONG_DOUBLE
  3623.                             pad_ptr = p;
  3624.  
  3625.                             if (dp->conversion == 'f' || dp->conversion == 'F')
  3626.                               {
  3627.                                 char *digits;
  3628.                                 size_t ndigits;
  3629.  
  3630.                                 digits =
  3631.                                   scale10_round_decimal_long_double (arg, precision);
  3632.                                 if (digits == NULL)
  3633.                                   {
  3634.                                     END_LONG_DOUBLE_ROUNDING ();
  3635.                                     goto out_of_memory;
  3636.                                   }
  3637.                                 ndigits = strlen (digits);
  3638.  
  3639.                                 if (ndigits > precision)
  3640.                                   do
  3641.                                     {
  3642.                                       --ndigits;
  3643.                                       *p++ = digits[ndigits];
  3644.                                     }
  3645.                                   while (ndigits > precision);
  3646.                                 else
  3647.                                   *p++ = '0';
  3648.                                 /* Here ndigits <= precision.  */
  3649.                                 if ((flags & FLAG_ALT) || precision > 0)
  3650.                                   {
  3651.                                     *p++ = decimal_point_char ();
  3652.                                     for (; precision > ndigits; precision--)
  3653.                                       *p++ = '0';
  3654.                                     while (ndigits > 0)
  3655.                                       {
  3656.                                         --ndigits;
  3657.                                         *p++ = digits[ndigits];
  3658.                                       }
  3659.                                   }
  3660.  
  3661.                                 free (digits);
  3662.                               }
  3663.                             else if (dp->conversion == 'e' || dp->conversion == 'E')
  3664.                               {
  3665.                                 int exponent;
  3666.  
  3667.                                 if (arg == 0.0L)
  3668.                                   {
  3669.                                     exponent = 0;
  3670.                                     *p++ = '0';
  3671.                                     if ((flags & FLAG_ALT) || precision > 0)
  3672.                                       {
  3673.                                         *p++ = decimal_point_char ();
  3674.                                         for (; precision > 0; precision--)
  3675.                                           *p++ = '0';
  3676.                                       }
  3677.                                   }
  3678.                                 else
  3679.                                   {
  3680.                                     /* arg > 0.0L.  */
  3681.                                     int adjusted;
  3682.                                     char *digits;
  3683.                                     size_t ndigits;
  3684.  
  3685.                                     exponent = floorlog10l (arg);
  3686.                                     adjusted = 0;
  3687.                                     for (;;)
  3688.                                       {
  3689.                                         digits =
  3690.                                           scale10_round_decimal_long_double (arg,
  3691.                                                                              (int)precision - exponent);
  3692.                                         if (digits == NULL)
  3693.                                           {
  3694.                                             END_LONG_DOUBLE_ROUNDING ();
  3695.                                             goto out_of_memory;
  3696.                                           }
  3697.                                         ndigits = strlen (digits);
  3698.  
  3699.                                         if (ndigits == precision + 1)
  3700.                                           break;
  3701.                                         if (ndigits < precision
  3702.                                             || ndigits > precision + 2)
  3703.                                           /* The exponent was not guessed
  3704.                                              precisely enough.  */
  3705.                                           abort ();
  3706.                                         if (adjusted)
  3707.                                           /* None of two values of exponent is
  3708.                                              the right one.  Prevent an endless
  3709.                                              loop.  */
  3710.                                           abort ();
  3711.                                         free (digits);
  3712.                                         if (ndigits == precision)
  3713.                                           exponent -= 1;
  3714.                                         else
  3715.                                           exponent += 1;
  3716.                                         adjusted = 1;
  3717.                                       }
  3718.                                     /* Here ndigits = precision+1.  */
  3719.                                     if (is_borderline (digits, precision))
  3720.                                       {
  3721.                                         /* Maybe the exponent guess was too high
  3722.                                            and a smaller exponent can be reached
  3723.                                            by turning a 10...0 into 9...9x.  */
  3724.                                         char *digits2 =
  3725.                                           scale10_round_decimal_long_double (arg,
  3726.                                                                              (int)precision - exponent + 1);
  3727.                                         if (digits2 == NULL)
  3728.                                           {
  3729.                                             free (digits);
  3730.                                             END_LONG_DOUBLE_ROUNDING ();
  3731.                                             goto out_of_memory;
  3732.                                           }
  3733.                                         if (strlen (digits2) == precision + 1)
  3734.                                           {
  3735.                                             free (digits);
  3736.                                             digits = digits2;
  3737.                                             exponent -= 1;
  3738.                                           }
  3739.                                         else
  3740.                                           free (digits2);
  3741.                                       }
  3742.                                     /* Here ndigits = precision+1.  */
  3743.  
  3744.                                     *p++ = digits[--ndigits];
  3745.                                     if ((flags & FLAG_ALT) || precision > 0)
  3746.                                       {
  3747.                                         *p++ = decimal_point_char ();
  3748.                                         while (ndigits > 0)
  3749.                                           {
  3750.                                             --ndigits;
  3751.                                             *p++ = digits[ndigits];
  3752.                                           }
  3753.                                       }
  3754.  
  3755.                                     free (digits);
  3756.                                   }
  3757.  
  3758.                                 *p++ = dp->conversion; /* 'e' or 'E' */
  3759. #   if WIDE_CHAR_VERSION
  3760.                                 {
  3761.                                   static const wchar_t decimal_format[] =
  3762.                                     { '%', '+', '.', '2', 'd', '\0' };
  3763.                                   SNPRINTF (p, 6 + 1, decimal_format, exponent);
  3764.                                 }
  3765.                                 while (*p != '\0')
  3766.                                   p++;
  3767. #   else
  3768.                                 if (sizeof (DCHAR_T) == 1)
  3769.                                   {
  3770.                                     sprintf ((char *) p, "%+.2d", exponent);
  3771.                                     while (*p != '\0')
  3772.                                       p++;
  3773.                                   }
  3774.                                 else
  3775.                                   {
  3776.                                     char expbuf[6 + 1];
  3777.                                     const char *ep;
  3778.                                     sprintf (expbuf, "%+.2d", exponent);
  3779.                                     for (ep = expbuf; (*p = *ep) != '\0'; ep++)
  3780.                                       p++;
  3781.                                   }
  3782. #   endif
  3783.                               }
  3784.                             else if (dp->conversion == 'g' || dp->conversion == 'G')
  3785.                               {
  3786.                                 if (precision == 0)
  3787.                                   precision = 1;
  3788.                                 /* precision >= 1.  */
  3789.  
  3790.                                 if (arg == 0.0L)
  3791.                                   /* The exponent is 0, >= -4, < precision.
  3792.                                      Use fixed-point notation.  */
  3793.                                   {
  3794.                                     size_t ndigits = precision;
  3795.                                     /* Number of trailing zeroes that have to be
  3796.                                        dropped.  */
  3797.                                     size_t nzeroes =
  3798.                                       (flags & FLAG_ALT ? 0 : precision - 1);
  3799.  
  3800.                                     --ndigits;
  3801.                                     *p++ = '0';
  3802.                                     if ((flags & FLAG_ALT) || ndigits > nzeroes)
  3803.                                       {
  3804.                                         *p++ = decimal_point_char ();
  3805.                                         while (ndigits > nzeroes)
  3806.                                           {
  3807.                                             --ndigits;
  3808.                                             *p++ = '0';
  3809.                                           }
  3810.                                       }
  3811.                                   }
  3812.                                 else
  3813.                                   {
  3814.                                     /* arg > 0.0L.  */
  3815.                                     int exponent;
  3816.                                     int adjusted;
  3817.                                     char *digits;
  3818.                                     size_t ndigits;
  3819.                                     size_t nzeroes;
  3820.  
  3821.                                     exponent = floorlog10l (arg);
  3822.                                     adjusted = 0;
  3823.                                     for (;;)
  3824.                                       {
  3825.                                         digits =
  3826.                                           scale10_round_decimal_long_double (arg,
  3827.                                                                              (int)(precision - 1) - exponent);
  3828.                                         if (digits == NULL)
  3829.                                           {
  3830.                                             END_LONG_DOUBLE_ROUNDING ();
  3831.                                             goto out_of_memory;
  3832.                                           }
  3833.                                         ndigits = strlen (digits);
  3834.  
  3835.                                         if (ndigits == precision)
  3836.                                           break;
  3837.                                         if (ndigits < precision - 1
  3838.                                             || ndigits > precision + 1)
  3839.                                           /* The exponent was not guessed
  3840.                                              precisely enough.  */
  3841.                                           abort ();
  3842.                                         if (adjusted)
  3843.                                           /* None of two values of exponent is
  3844.                                              the right one.  Prevent an endless
  3845.                                              loop.  */
  3846.                                           abort ();
  3847.                                         free (digits);
  3848.                                         if (ndigits < precision)
  3849.                                           exponent -= 1;
  3850.                                         else
  3851.                                           exponent += 1;
  3852.                                         adjusted = 1;
  3853.                                       }
  3854.                                     /* Here ndigits = precision.  */
  3855.                                     if (is_borderline (digits, precision - 1))
  3856.                                       {
  3857.                                         /* Maybe the exponent guess was too high
  3858.                                            and a smaller exponent can be reached
  3859.                                            by turning a 10...0 into 9...9x.  */
  3860.                                         char *digits2 =
  3861.                                           scale10_round_decimal_long_double (arg,
  3862.                                                                              (int)(precision - 1) - exponent + 1);
  3863.                                         if (digits2 == NULL)
  3864.                                           {
  3865.                                             free (digits);
  3866.                                             END_LONG_DOUBLE_ROUNDING ();
  3867.                                             goto out_of_memory;
  3868.                                           }
  3869.                                         if (strlen (digits2) == precision)
  3870.                                           {
  3871.                                             free (digits);
  3872.                                             digits = digits2;
  3873.                                             exponent -= 1;
  3874.                                           }
  3875.                                         else
  3876.                                           free (digits2);
  3877.                                       }
  3878.                                     /* Here ndigits = precision.  */
  3879.  
  3880.                                     /* Determine the number of trailing zeroes
  3881.                                        that have to be dropped.  */
  3882.                                     nzeroes = 0;
  3883.                                     if ((flags & FLAG_ALT) == 0)
  3884.                                       while (nzeroes < ndigits
  3885.                                              && digits[nzeroes] == '0')
  3886.                                         nzeroes++;
  3887.  
  3888.                                     /* The exponent is now determined.  */
  3889.                                     if (exponent >= -4
  3890.                                         && exponent < (long)precision)
  3891.                                       {
  3892.                                         /* Fixed-point notation:
  3893.                                            max(exponent,0)+1 digits, then the
  3894.                                            decimal point, then the remaining
  3895.                                            digits without trailing zeroes.  */
  3896.                                         if (exponent >= 0)
  3897.                                           {
  3898.                                             size_t count = exponent + 1;
  3899.                                             /* Note: count <= precision = ndigits.  */
  3900.                                             for (; count > 0; count--)
  3901.                                               *p++ = digits[--ndigits];
  3902.                                             if ((flags & FLAG_ALT) || ndigits > nzeroes)
  3903.                                               {
  3904.                                                 *p++ = decimal_point_char ();
  3905.                                                 while (ndigits > nzeroes)
  3906.                                                   {
  3907.                                                     --ndigits;
  3908.                                                     *p++ = digits[ndigits];
  3909.                                                   }
  3910.                                               }
  3911.                                           }
  3912.                                         else
  3913.                                           {
  3914.                                             size_t count = -exponent - 1;
  3915.                                             *p++ = '0';
  3916.                                             *p++ = decimal_point_char ();
  3917.                                             for (; count > 0; count--)
  3918.                                               *p++ = '0';
  3919.                                             while (ndigits > nzeroes)
  3920.                                               {
  3921.                                                 --ndigits;
  3922.                                                 *p++ = digits[ndigits];
  3923.                                               }
  3924.                                           }
  3925.                                       }
  3926.                                     else
  3927.                                       {
  3928.                                         /* Exponential notation.  */
  3929.                                         *p++ = digits[--ndigits];
  3930.                                         if ((flags & FLAG_ALT) || ndigits > nzeroes)
  3931.                                           {
  3932.                                             *p++ = decimal_point_char ();
  3933.                                             while (ndigits > nzeroes)
  3934.                                               {
  3935.                                                 --ndigits;
  3936.                                                 *p++ = digits[ndigits];
  3937.                                               }
  3938.                                           }
  3939.                                         *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
  3940. #   if WIDE_CHAR_VERSION
  3941.                                         {
  3942.                                           static const wchar_t decimal_format[] =
  3943.                                             { '%', '+', '.', '2', 'd', '\0' };
  3944.                                           SNPRINTF (p, 6 + 1, decimal_format, exponent);
  3945.                                         }
  3946.                                         while (*p != '\0')
  3947.                                           p++;
  3948. #   else
  3949.                                         if (sizeof (DCHAR_T) == 1)
  3950.                                           {
  3951.                                             sprintf ((char *) p, "%+.2d", exponent);
  3952.                                             while (*p != '\0')
  3953.                                               p++;
  3954.                                           }
  3955.                                         else
  3956.                                           {
  3957.                                             char expbuf[6 + 1];
  3958.                                             const char *ep;
  3959.                                             sprintf (expbuf, "%+.2d", exponent);
  3960.                                             for (ep = expbuf; (*p = *ep) != '\0'; ep++)
  3961.                                               p++;
  3962.                                           }
  3963. #   endif
  3964.                                       }
  3965.  
  3966.                                     free (digits);
  3967.                                   }
  3968.                               }
  3969.                             else
  3970.                               abort ();
  3971. #  else
  3972.                             /* arg is finite.  */
  3973.                             if (!(arg == 0.0L))
  3974.                               abort ();
  3975.  
  3976.                             pad_ptr = p;
  3977.  
  3978.                             if (dp->conversion == 'f' || dp->conversion == 'F')
  3979.                               {
  3980.                                 *p++ = '0';
  3981.                                 if ((flags & FLAG_ALT) || precision > 0)
  3982.                                   {
  3983.                                     *p++ = decimal_point_char ();
  3984.                                     for (; precision > 0; precision--)
  3985.                                       *p++ = '0';
  3986.                                   }
  3987.                               }
  3988.                             else if (dp->conversion == 'e' || dp->conversion == 'E')
  3989.                               {
  3990.                                 *p++ = '0';
  3991.                                 if ((flags & FLAG_ALT) || precision > 0)
  3992.                                   {
  3993.                                     *p++ = decimal_point_char ();
  3994.                                     for (; precision > 0; precision--)
  3995.                                       *p++ = '0';
  3996.                                   }
  3997.                                 *p++ = dp->conversion; /* 'e' or 'E' */
  3998.                                 *p++ = '+';
  3999.                                 *p++ = '0';
  4000.                                 *p++ = '0';
  4001.                               }
  4002.                             else if (dp->conversion == 'g' || dp->conversion == 'G')
  4003.                               {
  4004.                                 *p++ = '0';
  4005.                                 if (flags & FLAG_ALT)
  4006.                                   {
  4007.                                     size_t ndigits =
  4008.                                       (precision > 0 ? precision - 1 : 0);
  4009.                                     *p++ = decimal_point_char ();
  4010.                                     for (; ndigits > 0; --ndigits)
  4011.                                       *p++ = '0';
  4012.                                   }
  4013.                               }
  4014.                             else if (dp->conversion == 'a' || dp->conversion == 'A')
  4015.                               {
  4016.                                 *p++ = '0';
  4017.                                 *p++ = dp->conversion - 'A' + 'X';
  4018.                                 pad_ptr = p;
  4019.                                 *p++ = '0';
  4020.                                 if ((flags & FLAG_ALT) || precision > 0)
  4021.                                   {
  4022.                                     *p++ = decimal_point_char ();
  4023.                                     for (; precision > 0; precision--)
  4024.                                       *p++ = '0';
  4025.                                   }
  4026.                                 *p++ = dp->conversion - 'A' + 'P';
  4027.                                 *p++ = '+';
  4028.                                 *p++ = '0';
  4029.                               }
  4030.                             else
  4031.                               abort ();
  4032. #  endif
  4033.                           }
  4034.  
  4035.                         END_LONG_DOUBLE_ROUNDING ();
  4036.                       }
  4037.                   }
  4038. #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
  4039.                 else
  4040. #  endif
  4041. # endif
  4042. # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
  4043.                   {
  4044.                     double arg = a.arg[dp->arg_index].a.a_double;
  4045.  
  4046.                     if (isnand (arg))
  4047.                       {
  4048.                         if (dp->conversion >= 'A' && dp->conversion <= 'Z')
  4049.                           {
  4050.                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
  4051.                           }
  4052.                         else
  4053.                           {
  4054.                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
  4055.                           }
  4056.                       }
  4057.                     else
  4058.                       {
  4059.                         int sign = 0;
  4060.  
  4061.                         if (signbit (arg)) /* arg < 0.0 or negative zero */
  4062.                           {
  4063.                             sign = -1;
  4064.                             arg = -arg;
  4065.                           }
  4066.  
  4067.                         if (sign < 0)
  4068.                           *p++ = '-';
  4069.                         else if (flags & FLAG_SHOWSIGN)
  4070.                           *p++ = '+';
  4071.                         else if (flags & FLAG_SPACE)
  4072.                           *p++ = ' ';
  4073.  
  4074.                         if (arg > 0.0 && arg + arg == arg)
  4075.                           {
  4076.                             if (dp->conversion >= 'A' && dp->conversion <= 'Z')
  4077.                               {
  4078.                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
  4079.                               }
  4080.                             else
  4081.                               {
  4082.                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
  4083.                               }
  4084.                           }
  4085.                         else
  4086.                           {
  4087. #  if NEED_PRINTF_DOUBLE
  4088.                             pad_ptr = p;
  4089.  
  4090.                             if (dp->conversion == 'f' || dp->conversion == 'F')
  4091.                               {
  4092.                                 char *digits;
  4093.                                 size_t ndigits;
  4094.  
  4095.                                 digits =
  4096.                                   scale10_round_decimal_double (arg, precision);
  4097.                                 if (digits == NULL)
  4098.                                   goto out_of_memory;
  4099.                                 ndigits = strlen (digits);
  4100.  
  4101.                                 if (ndigits > precision)
  4102.                                   do
  4103.                                     {
  4104.                                       --ndigits;
  4105.                                       *p++ = digits[ndigits];
  4106.                                     }
  4107.                                   while (ndigits > precision);
  4108.                                 else
  4109.                                   *p++ = '0';
  4110.                                 /* Here ndigits <= precision.  */
  4111.                                 if ((flags & FLAG_ALT) || precision > 0)
  4112.                                   {
  4113.                                     *p++ = decimal_point_char ();
  4114.                                     for (; precision > ndigits; precision--)
  4115.                                       *p++ = '0';
  4116.                                     while (ndigits > 0)
  4117.                                       {
  4118.                                         --ndigits;
  4119.                                         *p++ = digits[ndigits];
  4120.                                       }
  4121.                                   }
  4122.  
  4123.                                 free (digits);
  4124.                               }
  4125.                             else if (dp->conversion == 'e' || dp->conversion == 'E')
  4126.                               {
  4127.                                 int exponent;
  4128.  
  4129.                                 if (arg == 0.0)
  4130.                                   {
  4131.                                     exponent = 0;
  4132.                                     *p++ = '0';
  4133.                                     if ((flags & FLAG_ALT) || precision > 0)
  4134.                                       {
  4135.                                         *p++ = decimal_point_char ();
  4136.                                         for (; precision > 0; precision--)
  4137.                                           *p++ = '0';
  4138.                                       }
  4139.                                   }
  4140.                                 else
  4141.                                   {
  4142.                                     /* arg > 0.0.  */
  4143.                                     int adjusted;
  4144.                                     char *digits;
  4145.                                     size_t ndigits;
  4146.  
  4147.                                     exponent = floorlog10 (arg);
  4148.                                     adjusted = 0;
  4149.                                     for (;;)
  4150.                                       {
  4151.                                         digits =
  4152.                                           scale10_round_decimal_double (arg,
  4153.                                                                         (int)precision - exponent);
  4154.                                         if (digits == NULL)
  4155.                                           goto out_of_memory;
  4156.                                         ndigits = strlen (digits);
  4157.  
  4158.                                         if (ndigits == precision + 1)
  4159.                                           break;
  4160.                                         if (ndigits < precision
  4161.                                             || ndigits > precision + 2)
  4162.                                           /* The exponent was not guessed
  4163.                                              precisely enough.  */
  4164.                                           abort ();
  4165.                                         if (adjusted)
  4166.                                           /* None of two values of exponent is
  4167.                                              the right one.  Prevent an endless
  4168.                                              loop.  */
  4169.                                           abort ();
  4170.                                         free (digits);
  4171.                                         if (ndigits == precision)
  4172.                                           exponent -= 1;
  4173.                                         else
  4174.                                           exponent += 1;
  4175.                                         adjusted = 1;
  4176.                                       }
  4177.                                     /* Here ndigits = precision+1.  */
  4178.                                     if (is_borderline (digits, precision))
  4179.                                       {
  4180.                                         /* Maybe the exponent guess was too high
  4181.                                            and a smaller exponent can be reached
  4182.                                            by turning a 10...0 into 9...9x.  */
  4183.                                         char *digits2 =
  4184.                                           scale10_round_decimal_double (arg,
  4185.                                                                         (int)precision - exponent + 1);
  4186.                                         if (digits2 == NULL)
  4187.                                           {
  4188.                                             free (digits);
  4189.                                             goto out_of_memory;
  4190.                                           }
  4191.                                         if (strlen (digits2) == precision + 1)
  4192.                                           {
  4193.                                             free (digits);
  4194.                                             digits = digits2;
  4195.                                             exponent -= 1;
  4196.                                           }
  4197.                                         else
  4198.                                           free (digits2);
  4199.                                       }
  4200.                                     /* Here ndigits = precision+1.  */
  4201.  
  4202.                                     *p++ = digits[--ndigits];
  4203.                                     if ((flags & FLAG_ALT) || precision > 0)
  4204.                                       {
  4205.                                         *p++ = decimal_point_char ();
  4206.                                         while (ndigits > 0)
  4207.                                           {
  4208.                                             --ndigits;
  4209.                                             *p++ = digits[ndigits];
  4210.                                           }
  4211.                                       }
  4212.  
  4213.                                     free (digits);
  4214.                                   }
  4215.  
  4216.                                 *p++ = dp->conversion; /* 'e' or 'E' */
  4217. #   if WIDE_CHAR_VERSION
  4218.                                 {
  4219.                                   static const wchar_t decimal_format[] =
  4220.                                     /* Produce the same number of exponent digits
  4221.                                        as the native printf implementation.  */
  4222. #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
  4223.                                     { '%', '+', '.', '3', 'd', '\0' };
  4224. #    else
  4225.                                     { '%', '+', '.', '2', 'd', '\0' };
  4226. #    endif
  4227.                                   SNPRINTF (p, 6 + 1, decimal_format, exponent);
  4228.                                 }
  4229.                                 while (*p != '\0')
  4230.                                   p++;
  4231. #   else
  4232.                                 {
  4233.                                   static const char decimal_format[] =
  4234.                                     /* Produce the same number of exponent digits
  4235.                                        as the native printf implementation.  */
  4236. #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
  4237.                                     "%+.3d";
  4238. #    else
  4239.                                     "%+.2d";
  4240. #    endif
  4241.                                   if (sizeof (DCHAR_T) == 1)
  4242.                                     {
  4243.                                       sprintf ((char *) p, decimal_format, exponent);
  4244.                                       while (*p != '\0')
  4245.                                         p++;
  4246.                                     }
  4247.                                   else
  4248.                                     {
  4249.                                       char expbuf[6 + 1];
  4250.                                       const char *ep;
  4251.                                       sprintf (expbuf, decimal_format, exponent);
  4252.                                       for (ep = expbuf; (*p = *ep) != '\0'; ep++)
  4253.                                         p++;
  4254.                                     }
  4255.                                 }
  4256. #   endif
  4257.                               }
  4258.                             else if (dp->conversion == 'g' || dp->conversion == 'G')
  4259.                               {
  4260.                                 if (precision == 0)
  4261.                                   precision = 1;
  4262.                                 /* precision >= 1.  */
  4263.  
  4264.                                 if (arg == 0.0)
  4265.                                   /* The exponent is 0, >= -4, < precision.
  4266.                                      Use fixed-point notation.  */
  4267.                                   {
  4268.                                     size_t ndigits = precision;
  4269.                                     /* Number of trailing zeroes that have to be
  4270.                                        dropped.  */
  4271.                                     size_t nzeroes =
  4272.                                       (flags & FLAG_ALT ? 0 : precision - 1);
  4273.  
  4274.                                     --ndigits;
  4275.                                     *p++ = '0';
  4276.                                     if ((flags & FLAG_ALT) || ndigits > nzeroes)
  4277.                                       {
  4278.                                         *p++ = decimal_point_char ();
  4279.                                         while (ndigits > nzeroes)
  4280.                                           {
  4281.                                             --ndigits;
  4282.                                             *p++ = '0';
  4283.                                           }
  4284.                                       }
  4285.                                   }
  4286.                                 else
  4287.                                   {
  4288.                                     /* arg > 0.0.  */
  4289.                                     int exponent;
  4290.                                     int adjusted;
  4291.                                     char *digits;
  4292.                                     size_t ndigits;
  4293.                                     size_t nzeroes;
  4294.  
  4295.                                     exponent = floorlog10 (arg);
  4296.                                     adjusted = 0;
  4297.                                     for (;;)
  4298.                                       {
  4299.                                         digits =
  4300.                                           scale10_round_decimal_double (arg,
  4301.                                                                         (int)(precision - 1) - exponent);
  4302.                                         if (digits == NULL)
  4303.                                           goto out_of_memory;
  4304.                                         ndigits = strlen (digits);
  4305.  
  4306.                                         if (ndigits == precision)
  4307.                                           break;
  4308.                                         if (ndigits < precision - 1
  4309.                                             || ndigits > precision + 1)
  4310.                                           /* The exponent was not guessed
  4311.                                              precisely enough.  */
  4312.                                           abort ();
  4313.                                         if (adjusted)
  4314.                                           /* None of two values of exponent is
  4315.                                              the right one.  Prevent an endless
  4316.                                              loop.  */
  4317.                                           abort ();
  4318.                                         free (digits);
  4319.                                         if (ndigits < precision)
  4320.                                           exponent -= 1;
  4321.                                         else
  4322.                                           exponent += 1;
  4323.                                         adjusted = 1;
  4324.                                       }
  4325.                                     /* Here ndigits = precision.  */
  4326.                                     if (is_borderline (digits, precision - 1))
  4327.                                       {
  4328.                                         /* Maybe the exponent guess was too high
  4329.                                            and a smaller exponent can be reached
  4330.                                            by turning a 10...0 into 9...9x.  */
  4331.                                         char *digits2 =
  4332.                                           scale10_round_decimal_double (arg,
  4333.                                                                         (int)(precision - 1) - exponent + 1);
  4334.                                         if (digits2 == NULL)
  4335.                                           {
  4336.                                             free (digits);
  4337.                                             goto out_of_memory;
  4338.                                           }
  4339.                                         if (strlen (digits2) == precision)
  4340.                                           {
  4341.                                             free (digits);
  4342.                                             digits = digits2;
  4343.                                             exponent -= 1;
  4344.                                           }
  4345.                                         else
  4346.                                           free (digits2);
  4347.                                       }
  4348.                                     /* Here ndigits = precision.  */
  4349.  
  4350.                                     /* Determine the number of trailing zeroes
  4351.                                        that have to be dropped.  */
  4352.                                     nzeroes = 0;
  4353.                                     if ((flags & FLAG_ALT) == 0)
  4354.                                       while (nzeroes < ndigits
  4355.                                              && digits[nzeroes] == '0')
  4356.                                         nzeroes++;
  4357.  
  4358.                                     /* The exponent is now determined.  */
  4359.                                     if (exponent >= -4
  4360.                                         && exponent < (long)precision)
  4361.                                       {
  4362.                                         /* Fixed-point notation:
  4363.                                            max(exponent,0)+1 digits, then the
  4364.                                            decimal point, then the remaining
  4365.                                            digits without trailing zeroes.  */
  4366.                                         if (exponent >= 0)
  4367.                                           {
  4368.                                             size_t count = exponent + 1;
  4369.                                             /* Note: count <= precision = ndigits.  */
  4370.                                             for (; count > 0; count--)
  4371.                                               *p++ = digits[--ndigits];
  4372.                                             if ((flags & FLAG_ALT) || ndigits > nzeroes)
  4373.                                               {
  4374.                                                 *p++ = decimal_point_char ();
  4375.                                                 while (ndigits > nzeroes)
  4376.                                                   {
  4377.                                                     --ndigits;
  4378.                                                     *p++ = digits[ndigits];
  4379.                                                   }
  4380.                                               }
  4381.                                           }
  4382.                                         else
  4383.                                           {
  4384.                                             size_t count = -exponent - 1;
  4385.                                             *p++ = '0';
  4386.                                             *p++ = decimal_point_char ();
  4387.                                             for (; count > 0; count--)
  4388.                                               *p++ = '0';
  4389.                                             while (ndigits > nzeroes)
  4390.                                               {
  4391.                                                 --ndigits;
  4392.                                                 *p++ = digits[ndigits];
  4393.                                               }
  4394.                                           }
  4395.                                       }
  4396.                                     else
  4397.                                       {
  4398.                                         /* Exponential notation.  */
  4399.                                         *p++ = digits[--ndigits];
  4400.                                         if ((flags & FLAG_ALT) || ndigits > nzeroes)
  4401.                                           {
  4402.                                             *p++ = decimal_point_char ();
  4403.                                             while (ndigits > nzeroes)
  4404.                                               {
  4405.                                                 --ndigits;
  4406.                                                 *p++ = digits[ndigits];
  4407.                                               }
  4408.                                           }
  4409.                                         *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
  4410. #   if WIDE_CHAR_VERSION
  4411.                                         {
  4412.                                           static const wchar_t decimal_format[] =
  4413.                                             /* Produce the same number of exponent digits
  4414.                                                as the native printf implementation.  */
  4415. #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
  4416.                                             { '%', '+', '.', '3', 'd', '\0' };
  4417. #    else
  4418.                                             { '%', '+', '.', '2', 'd', '\0' };
  4419. #    endif
  4420.                                           SNPRINTF (p, 6 + 1, decimal_format, exponent);
  4421.                                         }
  4422.                                         while (*p != '\0')
  4423.                                           p++;
  4424. #   else
  4425.                                         {
  4426.                                           static const char decimal_format[] =
  4427.                                             /* Produce the same number of exponent digits
  4428.                                                as the native printf implementation.  */
  4429. #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
  4430.                                             "%+.3d";
  4431. #    else
  4432.                                             "%+.2d";
  4433. #    endif
  4434.                                           if (sizeof (DCHAR_T) == 1)
  4435.                                             {
  4436.                                               sprintf ((char *) p, decimal_format, exponent);
  4437.                                               while (*p != '\0')
  4438.                                                 p++;
  4439.                                             }
  4440.                                           else
  4441.                                             {
  4442.                                               char expbuf[6 + 1];
  4443.                                               const char *ep;
  4444.                                               sprintf (expbuf, decimal_format, exponent);
  4445.                                               for (ep = expbuf; (*p = *ep) != '\0'; ep++)
  4446.                                                 p++;
  4447.                                             }
  4448.                                         }
  4449. #   endif
  4450.                                       }
  4451.  
  4452.                                     free (digits);
  4453.                                   }
  4454.                               }
  4455.                             else
  4456.                               abort ();
  4457. #  else
  4458.                             /* arg is finite.  */
  4459.                             if (!(arg == 0.0))
  4460.                               abort ();
  4461.  
  4462.                             pad_ptr = p;
  4463.  
  4464.                             if (dp->conversion == 'f' || dp->conversion == 'F')
  4465.                               {
  4466.                                 *p++ = '0';
  4467.                                 if ((flags & FLAG_ALT) || precision > 0)
  4468.                                   {
  4469.                                     *p++ = decimal_point_char ();
  4470.                                     for (; precision > 0; precision--)
  4471.                                       *p++ = '0';
  4472.                                   }
  4473.                               }
  4474.                             else if (dp->conversion == 'e' || dp->conversion == 'E')
  4475.                               {
  4476.                                 *p++ = '0';
  4477.                                 if ((flags & FLAG_ALT) || precision > 0)
  4478.                                   {
  4479.                                     *p++ = decimal_point_char ();
  4480.                                     for (; precision > 0; precision--)
  4481.                                       *p++ = '0';
  4482.                                   }
  4483.                                 *p++ = dp->conversion; /* 'e' or 'E' */
  4484.                                 *p++ = '+';
  4485.                                 /* Produce the same number of exponent digits as
  4486.                                    the native printf implementation.  */
  4487. #   if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
  4488.                                 *p++ = '0';
  4489. #   endif
  4490.                                 *p++ = '0';
  4491.                                 *p++ = '0';
  4492.                               }
  4493.                             else if (dp->conversion == 'g' || dp->conversion == 'G')
  4494.                               {
  4495.                                 *p++ = '0';
  4496.                                 if (flags & FLAG_ALT)
  4497.                                   {
  4498.                                     size_t ndigits =
  4499.                                       (precision > 0 ? precision - 1 : 0);
  4500.                                     *p++ = decimal_point_char ();
  4501.                                     for (; ndigits > 0; --ndigits)
  4502.                                       *p++ = '0';
  4503.                                   }
  4504.                               }
  4505.                             else
  4506.                               abort ();
  4507. #  endif
  4508.                           }
  4509.                       }
  4510.                   }
  4511. # endif
  4512.  
  4513.                 /* The generated string now extends from tmp to p, with the
  4514.                    zero padding insertion point being at pad_ptr.  */
  4515.                 if (has_width && p - tmp < width)
  4516.                   {
  4517.                     size_t pad = width - (p - tmp);
  4518.                     DCHAR_T *end = p + pad;
  4519.  
  4520.                     if (flags & FLAG_LEFT)
  4521.                       {
  4522.                         /* Pad with spaces on the right.  */
  4523.                         for (; pad > 0; pad--)
  4524.                           *p++ = ' ';
  4525.                       }
  4526.                     else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
  4527.                       {
  4528.                         /* Pad with zeroes.  */
  4529.                         DCHAR_T *q = end;
  4530.  
  4531.                         while (p > pad_ptr)
  4532.                           *--q = *--p;
  4533.                         for (; pad > 0; pad--)
  4534.                           *p++ = '0';
  4535.                       }
  4536.                     else
  4537.                       {
  4538.                         /* Pad with spaces on the left.  */
  4539.                         DCHAR_T *q = end;
  4540.  
  4541.                         while (p > tmp)
  4542.                           *--q = *--p;
  4543.                         for (; pad > 0; pad--)
  4544.                           *p++ = ' ';
  4545.                       }
  4546.  
  4547.                     p = end;
  4548.                   }
  4549.  
  4550.                 {
  4551.                   size_t count = p - tmp;
  4552.  
  4553.                   if (count >= tmp_length)
  4554.                     /* tmp_length was incorrectly calculated - fix the
  4555.                        code above!  */
  4556.                     abort ();
  4557.  
  4558.                   /* Make room for the result.  */
  4559.                   if (count >= allocated - length)
  4560.                     {
  4561.                       size_t n = xsum (length, count);
  4562.  
  4563.                       ENSURE_ALLOCATION (n);
  4564.                     }
  4565.  
  4566.                   /* Append the result.  */
  4567.                   memcpy (result + length, tmp, count * sizeof (DCHAR_T));
  4568.                   if (tmp != tmpbuf)
  4569.                     free (tmp);
  4570.                   length += count;
  4571.                 }
  4572.               }
  4573. #endif
  4574.             else
  4575.               {
  4576.                 arg_type type = a.arg[dp->arg_index].type;
  4577.                 int flags = dp->flags;
  4578. #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
  4579.                 int has_width;
  4580.                 size_t width;
  4581. #endif
  4582. #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
  4583.                 int has_precision;
  4584.                 size_t precision;
  4585. #endif
  4586. #if NEED_PRINTF_UNBOUNDED_PRECISION
  4587.                 int prec_ourselves;
  4588. #else
  4589. #               define prec_ourselves 0
  4590. #endif
  4591. #if NEED_PRINTF_FLAG_LEFTADJUST
  4592. #               define pad_ourselves 1
  4593. #elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
  4594.                 int pad_ourselves;
  4595. #else
  4596. #               define pad_ourselves 0
  4597. #endif
  4598.                 TCHAR_T *fbp;
  4599.                 unsigned int prefix_count;
  4600.                 int prefixes[2] IF_LINT (= { 0 });
  4601. #if !USE_SNPRINTF
  4602.                 size_t tmp_length;
  4603.                 TCHAR_T tmpbuf[700];
  4604.                 TCHAR_T *tmp;
  4605. #endif
  4606.  
  4607. #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
  4608.                 has_width = 0;
  4609.                 width = 0;
  4610.                 if (dp->width_start != dp->width_end)
  4611.                   {
  4612.                     if (dp->width_arg_index != ARG_NONE)
  4613.                       {
  4614.                         int arg;
  4615.  
  4616.                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
  4617.                           abort ();
  4618.                         arg = a.arg[dp->width_arg_index].a.a_int;
  4619.                         if (arg < 0)
  4620.                           {
  4621.                             /* "A negative field width is taken as a '-' flag
  4622.                                 followed by a positive field width."  */
  4623.                             flags |= FLAG_LEFT;
  4624.                             width = (unsigned int) (-arg);
  4625.                           }
  4626.                         else
  4627.                           width = arg;
  4628.                       }
  4629.                     else
  4630.                       {
  4631.                         const FCHAR_T *digitp = dp->width_start;
  4632.  
  4633.                         do
  4634.                           width = xsum (xtimes (width, 10), *digitp++ - '0');
  4635.                         while (digitp != dp->width_end);
  4636.                       }
  4637.                     has_width = 1;
  4638.                   }
  4639. #endif
  4640.  
  4641. #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
  4642.                 has_precision = 0;
  4643.                 precision = 6;
  4644.                 if (dp->precision_start != dp->precision_end)
  4645.                   {
  4646.                     if (dp->precision_arg_index != ARG_NONE)
  4647.                       {
  4648.                         int arg;
  4649.  
  4650.                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
  4651.                           abort ();
  4652.                         arg = a.arg[dp->precision_arg_index].a.a_int;
  4653.                         /* "A negative precision is taken as if the precision
  4654.                             were omitted."  */
  4655.                         if (arg >= 0)
  4656.                           {
  4657.                             precision = arg;
  4658.                             has_precision = 1;
  4659.                           }
  4660.                       }
  4661.                     else
  4662.                       {
  4663.                         const FCHAR_T *digitp = dp->precision_start + 1;
  4664.  
  4665.                         precision = 0;
  4666.                         while (digitp != dp->precision_end)
  4667.                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
  4668.                         has_precision = 1;
  4669.                       }
  4670.                   }
  4671. #endif
  4672.  
  4673.                 /* Decide whether to handle the precision ourselves.  */
  4674. #if NEED_PRINTF_UNBOUNDED_PRECISION
  4675.                 switch (dp->conversion)
  4676.                   {
  4677.                   case 'd': case 'i': case 'u':
  4678.                   case 'o':
  4679.                   case 'x': case 'X': case 'p':
  4680.                     prec_ourselves = has_precision && (precision > 0);
  4681.                     break;
  4682.                   default:
  4683.                     prec_ourselves = 0;
  4684.                     break;
  4685.                   }
  4686. #endif
  4687.  
  4688.                 /* Decide whether to perform the padding ourselves.  */
  4689. #if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
  4690.                 switch (dp->conversion)
  4691.                   {
  4692. # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
  4693.                   /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
  4694.                      to perform the padding after this conversion.  Functions
  4695.                      with unistdio extensions perform the padding based on
  4696.                      character count rather than element count.  */
  4697.                   case 'c': case 's':
  4698. # endif
  4699. # if NEED_PRINTF_FLAG_ZERO
  4700.                   case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
  4701.                   case 'a': case 'A':
  4702. # endif
  4703.                     pad_ourselves = 1;
  4704.                     break;
  4705.                   default:
  4706.                     pad_ourselves = prec_ourselves;
  4707.                     break;
  4708.                   }
  4709. #endif
  4710.  
  4711. #if !USE_SNPRINTF
  4712.                 /* Allocate a temporary buffer of sufficient size for calling
  4713.                    sprintf.  */
  4714.                 tmp_length =
  4715.                   MAX_ROOM_NEEDED (&a, dp->arg_index, dp->conversion, type,
  4716.                                    flags, width, has_precision, precision,
  4717.                                    pad_ourselves);
  4718.  
  4719.                 if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T))
  4720.                   tmp = tmpbuf;
  4721.                 else
  4722.                   {
  4723.                     size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T));
  4724.  
  4725.                     if (size_overflow_p (tmp_memsize))
  4726.                       /* Overflow, would lead to out of memory.  */
  4727.                       goto out_of_memory;
  4728.                     tmp = (TCHAR_T *) malloc (tmp_memsize);
  4729.                     if (tmp == NULL)
  4730.                       /* Out of memory.  */
  4731.                       goto out_of_memory;
  4732.                   }
  4733. #endif
  4734.  
  4735.                 /* Construct the format string for calling snprintf or
  4736.                    sprintf.  */
  4737.                 fbp = buf;
  4738.                 *fbp++ = '%';
  4739. #if NEED_PRINTF_FLAG_GROUPING
  4740.                 /* The underlying implementation doesn't support the ' flag.
  4741.                    Produce no grouping characters in this case; this is
  4742.                    acceptable because the grouping is locale dependent.  */
  4743. #else
  4744.                 if (flags & FLAG_GROUP)
  4745.                   *fbp++ = '\'';
  4746. #endif
  4747.                 if (flags & FLAG_LEFT)
  4748.                   *fbp++ = '-';
  4749.                 if (flags & FLAG_SHOWSIGN)
  4750.                   *fbp++ = '+';
  4751.                 if (flags & FLAG_SPACE)
  4752.                   *fbp++ = ' ';
  4753.                 if (flags & FLAG_ALT)
  4754.                   *fbp++ = '#';
  4755.                 if (!pad_ourselves)
  4756.                   {
  4757.                     if (flags & FLAG_ZERO)
  4758.                       *fbp++ = '0';
  4759.                     if (dp->width_start != dp->width_end)
  4760.                       {
  4761.                         size_t n = dp->width_end - dp->width_start;
  4762.                         /* The width specification is known to consist only
  4763.                            of standard ASCII characters.  */
  4764.                         if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
  4765.                           {
  4766.                             memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T));
  4767.                             fbp += n;
  4768.                           }
  4769.                         else
  4770.                           {
  4771.                             const FCHAR_T *mp = dp->width_start;
  4772.                             do
  4773.                               *fbp++ = (unsigned char) *mp++;
  4774.                             while (--n > 0);
  4775.                           }
  4776.                       }
  4777.                   }
  4778.                 if (!prec_ourselves)
  4779.                   {
  4780.                     if (dp->precision_start != dp->precision_end)
  4781.                       {
  4782.                         size_t n = dp->precision_end - dp->precision_start;
  4783.                         /* The precision specification is known to consist only
  4784.                            of standard ASCII characters.  */
  4785.                         if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
  4786.                           {
  4787.                             memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T));
  4788.                             fbp += n;
  4789.                           }
  4790.                         else
  4791.                           {
  4792.                             const FCHAR_T *mp = dp->precision_start;
  4793.                             do
  4794.                               *fbp++ = (unsigned char) *mp++;
  4795.                             while (--n > 0);
  4796.                           }
  4797.                       }
  4798.                   }
  4799.  
  4800.                 switch (type)
  4801.                   {
  4802. #if HAVE_LONG_LONG_INT
  4803.                   case TYPE_LONGLONGINT:
  4804.                   case TYPE_ULONGLONGINT:
  4805. # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
  4806.                     *fbp++ = 'I';
  4807.                     *fbp++ = '6';
  4808.                     *fbp++ = '4';
  4809.                     break;
  4810. # else
  4811.                     *fbp++ = 'l';
  4812.                     /*FALLTHROUGH*/
  4813. # endif
  4814. #endif
  4815.                   case TYPE_LONGINT:
  4816.                   case TYPE_ULONGINT:
  4817. #if HAVE_WINT_T
  4818.                   case TYPE_WIDE_CHAR:
  4819. #endif
  4820. #if HAVE_WCHAR_T
  4821.                   case TYPE_WIDE_STRING:
  4822. #endif
  4823.                     *fbp++ = 'l';
  4824.                     break;
  4825.                   case TYPE_LONGDOUBLE:
  4826.                     *fbp++ = 'L';
  4827.                     break;
  4828.                   default:
  4829.                     break;
  4830.                   }
  4831. #if NEED_PRINTF_DIRECTIVE_F
  4832.                 if (dp->conversion == 'F')
  4833.                   *fbp = 'f';
  4834.                 else
  4835. #endif
  4836.                   *fbp = dp->conversion;
  4837. #if USE_SNPRINTF
  4838. # if !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
  4839.                 fbp[1] = '%';
  4840.                 fbp[2] = 'n';
  4841.                 fbp[3] = '\0';
  4842. # else
  4843.                 /* On glibc2 systems from glibc >= 2.3 - probably also older
  4844.                    ones - we know that snprintf's returns value conforms to
  4845.                    ISO C 99: the gl_SNPRINTF_DIRECTIVE_N test passes.
  4846.                    Therefore we can avoid using %n in this situation.
  4847.                    On glibc2 systems from 2004-10-18 or newer, the use of %n
  4848.                    in format strings in writable memory may crash the program
  4849.                    (if compiled with _FORTIFY_SOURCE=2), so we should avoid it
  4850.                    in this situation.  */
  4851.                 /* On native Win32 systems (such as mingw), we can avoid using
  4852.                    %n because:
  4853.                      - Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
  4854.                        snprintf does not write more than the specified number
  4855.                        of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes
  4856.                        '4', '5', '6' into buf, not '4', '5', '\0'.)
  4857.                      - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
  4858.                        allows us to recognize the case of an insufficient
  4859.                        buffer size: it returns -1 in this case.
  4860.                    On native Win32 systems (such as mingw) where the OS is
  4861.                    Windows Vista, the use of %n in format strings by default
  4862.                    crashes the program. See
  4863.                      <http://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
  4864.                      <http://msdn2.microsoft.com/en-us/library/ms175782(VS.80).aspx>
  4865.                    So we should avoid %n in this situation.  */
  4866.                 fbp[1] = '\0';
  4867. # endif
  4868. #else
  4869.                 fbp[1] = '\0';
  4870. #endif
  4871.  
  4872.                 /* Construct the arguments for calling snprintf or sprintf.  */
  4873.                 prefix_count = 0;
  4874.                 if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
  4875.                   {
  4876.                     if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
  4877.                       abort ();
  4878.                     prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
  4879.                   }
  4880.                 if (!prec_ourselves && dp->precision_arg_index != ARG_NONE)
  4881.                   {
  4882.                     if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
  4883.                       abort ();
  4884.                     prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
  4885.                   }
  4886.  
  4887. #if USE_SNPRINTF
  4888.                 /* The SNPRINTF result is appended after result[0..length].
  4889.                    The latter is an array of DCHAR_T; SNPRINTF appends an
  4890.                    array of TCHAR_T to it.  This is possible because
  4891.                    sizeof (TCHAR_T) divides sizeof (DCHAR_T) and
  4892.                    alignof (TCHAR_T) <= alignof (DCHAR_T).  */
  4893. # define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T))
  4894.                 /* Ensure that maxlen below will be >= 2.  Needed on BeOS,
  4895.                    where an snprintf() with maxlen==1 acts like sprintf().  */
  4896.                 ENSURE_ALLOCATION (xsum (length,
  4897.                                          (2 + TCHARS_PER_DCHAR - 1)
  4898.                                          / TCHARS_PER_DCHAR));
  4899.                 /* Prepare checking whether snprintf returns the count
  4900.                    via %n.  */
  4901.                 *(TCHAR_T *) (result + length) = '\0';
  4902. #endif
  4903.  
  4904.                 for (;;)
  4905.                   {
  4906.                     int count = -1;
  4907.  
  4908. #if USE_SNPRINTF
  4909.                     int retcount = 0;
  4910.                     size_t maxlen = allocated - length;
  4911.                     /* SNPRINTF can fail if its second argument is
  4912.                        > INT_MAX.  */
  4913.                     if (maxlen > INT_MAX / TCHARS_PER_DCHAR)
  4914.                       maxlen = INT_MAX / TCHARS_PER_DCHAR;
  4915.                     maxlen = maxlen * TCHARS_PER_DCHAR;
  4916. # define SNPRINTF_BUF(arg) \
  4917.                     switch (prefix_count)                                   \
  4918.                       {                                                     \
  4919.                       case 0:                                               \
  4920.                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
  4921.                                              maxlen, buf,                   \
  4922.                                              arg, &count);                  \
  4923.                         break;                                              \
  4924.                       case 1:                                               \
  4925.                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
  4926.                                              maxlen, buf,                   \
  4927.                                              prefixes[0], arg, &count);     \
  4928.                         break;                                              \
  4929.                       case 2:                                               \
  4930.                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
  4931.                                              maxlen, buf,                   \
  4932.                                              prefixes[0], prefixes[1], arg, \
  4933.                                              &count);                       \
  4934.                         break;                                              \
  4935.                       default:                                              \
  4936.                         abort ();                                           \
  4937.                       }
  4938. #else
  4939. # define SNPRINTF_BUF(arg) \
  4940.                     switch (prefix_count)                                   \
  4941.                       {                                                     \
  4942.                       case 0:                                               \
  4943.                         count = sprintf (tmp, buf, arg);                    \
  4944.                         break;                                              \
  4945.                       case 1:                                               \
  4946.                         count = sprintf (tmp, buf, prefixes[0], arg);       \
  4947.                         break;                                              \
  4948.                       case 2:                                               \
  4949.                         count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
  4950.                                          arg);                              \
  4951.                         break;                                              \
  4952.                       default:                                              \
  4953.                         abort ();                                           \
  4954.                       }
  4955. #endif
  4956.  
  4957.                     errno = 0;
  4958.                     switch (type)
  4959.                       {
  4960.                       case TYPE_SCHAR:
  4961.                         {
  4962.                           int arg = a.arg[dp->arg_index].a.a_schar;
  4963.                           SNPRINTF_BUF (arg);
  4964.                         }
  4965.                         break;
  4966.                       case TYPE_UCHAR:
  4967.                         {
  4968.                           unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
  4969.                           SNPRINTF_BUF (arg);
  4970.                         }
  4971.                         break;
  4972.                       case TYPE_SHORT:
  4973.                         {
  4974.                           int arg = a.arg[dp->arg_index].a.a_short;
  4975.                           SNPRINTF_BUF (arg);
  4976.                         }
  4977.                         break;
  4978.                       case TYPE_USHORT:
  4979.                         {
  4980.                           unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
  4981.                           SNPRINTF_BUF (arg);
  4982.                         }
  4983.                         break;
  4984.                       case TYPE_INT:
  4985.                         {
  4986.                           int arg = a.arg[dp->arg_index].a.a_int;
  4987.                           SNPRINTF_BUF (arg);
  4988.                         }
  4989.                         break;
  4990.                       case TYPE_UINT:
  4991.                         {
  4992.                           unsigned int arg = a.arg[dp->arg_index].a.a_uint;
  4993.                           SNPRINTF_BUF (arg);
  4994.                         }
  4995.                         break;
  4996.                       case TYPE_LONGINT:
  4997.                         {
  4998.                           long int arg = a.arg[dp->arg_index].a.a_longint;
  4999.                           SNPRINTF_BUF (arg);
  5000.                         }
  5001.                         break;
  5002.                       case TYPE_ULONGINT:
  5003.                         {
  5004.                           unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
  5005.                           SNPRINTF_BUF (arg);
  5006.                         }
  5007.                         break;
  5008. #if HAVE_LONG_LONG_INT
  5009.                       case TYPE_LONGLONGINT:
  5010.                         {
  5011.                           long long int arg = a.arg[dp->arg_index].a.a_longlongint;
  5012.                           SNPRINTF_BUF (arg);
  5013.                         }
  5014.                         break;
  5015.                       case TYPE_ULONGLONGINT:
  5016.                         {
  5017.                           unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
  5018.                           SNPRINTF_BUF (arg);
  5019.                         }
  5020.                         break;
  5021. #endif
  5022.                       case TYPE_DOUBLE:
  5023.                         {
  5024.                           double arg = a.arg[dp->arg_index].a.a_double;
  5025.                           SNPRINTF_BUF (arg);
  5026.                         }
  5027.                         break;
  5028.                       case TYPE_LONGDOUBLE:
  5029.                         {
  5030.                           long double arg = a.arg[dp->arg_index].a.a_longdouble;
  5031.                           SNPRINTF_BUF (arg);
  5032.                         }
  5033.                         break;
  5034.                       case TYPE_CHAR:
  5035.                         {
  5036.                           int arg = a.arg[dp->arg_index].a.a_char;
  5037.                           SNPRINTF_BUF (arg);
  5038.                         }
  5039.                         break;
  5040. #if HAVE_WINT_T
  5041.                       case TYPE_WIDE_CHAR:
  5042.                         {
  5043.                           wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
  5044.                           SNPRINTF_BUF (arg);
  5045.                         }
  5046.                         break;
  5047. #endif
  5048.                       case TYPE_STRING:
  5049.                         {
  5050.                           const char *arg = a.arg[dp->arg_index].a.a_string;
  5051.                           SNPRINTF_BUF (arg);
  5052.                         }
  5053.                         break;
  5054. #if HAVE_WCHAR_T
  5055.                       case TYPE_WIDE_STRING:
  5056.                         {
  5057.                           const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
  5058.                           SNPRINTF_BUF (arg);
  5059.                         }
  5060.                         break;
  5061. #endif
  5062.                       case TYPE_POINTER:
  5063.                         {
  5064.                           void *arg = a.arg[dp->arg_index].a.a_pointer;
  5065.                           SNPRINTF_BUF (arg);
  5066.                         }
  5067.                         break;
  5068.                       default:
  5069.                         abort ();
  5070.                       }
  5071.  
  5072. #if USE_SNPRINTF
  5073.                     /* Portability: Not all implementations of snprintf()
  5074.                        are ISO C 99 compliant.  Determine the number of
  5075.                        bytes that snprintf() has produced or would have
  5076.                        produced.  */
  5077.                     if (count >= 0)
  5078.                       {
  5079.                         /* Verify that snprintf() has NUL-terminated its
  5080.                            result.  */
  5081.                         if (count < maxlen
  5082.                             && ((TCHAR_T *) (result + length)) [count] != '\0')
  5083.                           abort ();
  5084.                         /* Portability hack.  */
  5085.                         if (retcount > count)
  5086.                           count = retcount;
  5087.                       }
  5088.                     else
  5089.                       {
  5090.                         /* snprintf() doesn't understand the '%n'
  5091.                            directive.  */
  5092.                         if (fbp[1] != '\0')
  5093.                           {
  5094.                             /* Don't use the '%n' directive; instead, look
  5095.                                at the snprintf() return value.  */
  5096.                             fbp[1] = '\0';
  5097.                             continue;
  5098.                           }
  5099.                         else
  5100.                           {
  5101.                             /* Look at the snprintf() return value.  */
  5102.                             if (retcount < 0)
  5103.                               {
  5104. # if !HAVE_SNPRINTF_RETVAL_C99
  5105.                                 /* HP-UX 10.20 snprintf() is doubly deficient:
  5106.                                    It doesn't understand the '%n' directive,
  5107.                                    *and* it returns -1 (rather than the length
  5108.                                    that would have been required) when the
  5109.                                    buffer is too small.
  5110.                                    But a failure at this point can also come
  5111.                                    from other reasons than a too small buffer,
  5112.                                    such as an invalid wide string argument to
  5113.                                    the %ls directive, or possibly an invalid
  5114.                                    floating-point argument.  */
  5115.                                 size_t tmp_length =
  5116.                                   MAX_ROOM_NEEDED (&a, dp->arg_index,
  5117.                                                    dp->conversion, type, flags,
  5118.                                                    width, has_precision,
  5119.                                                    precision, pad_ourselves);
  5120.  
  5121.                                 if (maxlen < tmp_length)
  5122.                                   {
  5123.                                     /* Make more room.  But try to do through
  5124.                                        this reallocation only once.  */
  5125.                                     size_t bigger_need =
  5126.                                       xsum (length,
  5127.                                             xsum (tmp_length,
  5128.                                                   TCHARS_PER_DCHAR - 1)
  5129.                                             / TCHARS_PER_DCHAR);
  5130.                                     /* And always grow proportionally.
  5131.                                        (There may be several arguments, each
  5132.                                        needing a little more room than the
  5133.                                        previous one.)  */
  5134.                                     size_t bigger_need2 =
  5135.                                       xsum (xtimes (allocated, 2), 12);
  5136.                                     if (bigger_need < bigger_need2)
  5137.                                       bigger_need = bigger_need2;
  5138.                                     ENSURE_ALLOCATION (bigger_need);
  5139.                                     continue;
  5140.                                   }
  5141. # endif
  5142.                               }
  5143.                             else
  5144.                               count = retcount;
  5145.                           }
  5146.                       }
  5147. #endif
  5148.  
  5149.                     /* Attempt to handle failure.  */
  5150.                     if (count < 0)
  5151.                       {
  5152.                         /* SNPRINTF or sprintf failed.  Save and use the errno
  5153.                            that it has set, if any.  */
  5154.                         int saved_errno = errno;
  5155.  
  5156.                         if (!(result == resultbuf || result == NULL))
  5157.                           free (result);
  5158.                         if (buf_malloced != NULL)
  5159.                           free (buf_malloced);
  5160.                         CLEANUP ();
  5161.                         errno =
  5162.                           (saved_errno != 0
  5163.                            ? saved_errno
  5164.                            : (dp->conversion == 'c' || dp->conversion == 's'
  5165.                               ? EILSEQ
  5166.                               : EINVAL));
  5167.                         return NULL;
  5168.                       }
  5169.  
  5170. #if USE_SNPRINTF
  5171.                     /* Handle overflow of the allocated buffer.
  5172.                        If such an overflow occurs, a C99 compliant snprintf()
  5173.                        returns a count >= maxlen.  However, a non-compliant
  5174.                        snprintf() function returns only count = maxlen - 1.  To
  5175.                        cover both cases, test whether count >= maxlen - 1.  */
  5176.                     if ((unsigned int) count + 1 >= maxlen)
  5177.                       {
  5178.                         /* If maxlen already has attained its allowed maximum,
  5179.                            allocating more memory will not increase maxlen.
  5180.                            Instead of looping, bail out.  */
  5181.                         if (maxlen == INT_MAX / TCHARS_PER_DCHAR)
  5182.                           goto overflow;
  5183.                         else
  5184.                           {
  5185.                             /* Need at least (count + 1) * sizeof (TCHAR_T)
  5186.                                bytes.  (The +1 is for the trailing NUL.)
  5187.                                But ask for (count + 2) * sizeof (TCHAR_T)
  5188.                                bytes, so that in the next round, we likely get
  5189.                                  maxlen > (unsigned int) count + 1
  5190.                                and so we don't get here again.
  5191.                                And allocate proportionally, to avoid looping
  5192.                                eternally if snprintf() reports a too small
  5193.                                count.  */
  5194.                             size_t n =
  5195.                               xmax (xsum (length,
  5196.                                           ((unsigned int) count + 2
  5197.                                            + TCHARS_PER_DCHAR - 1)
  5198.                                           / TCHARS_PER_DCHAR),
  5199.                                     xtimes (allocated, 2));
  5200.  
  5201.                             ENSURE_ALLOCATION (n);
  5202.                             continue;
  5203.                           }
  5204.                       }
  5205. #endif
  5206.  
  5207. #if NEED_PRINTF_UNBOUNDED_PRECISION
  5208.                     if (prec_ourselves)
  5209.                       {
  5210.                         /* Handle the precision.  */
  5211.                         TCHAR_T *prec_ptr =
  5212. # if USE_SNPRINTF
  5213.                           (TCHAR_T *) (result + length);
  5214. # else
  5215.                           tmp;
  5216. # endif
  5217.                         size_t prefix_count;
  5218.                         size_t move;
  5219.  
  5220.                         prefix_count = 0;
  5221.                         /* Put the additional zeroes after the sign.  */
  5222.                         if (count >= 1
  5223.                             && (*prec_ptr == '-' || *prec_ptr == '+'
  5224.                                 || *prec_ptr == ' '))
  5225.                           prefix_count = 1;
  5226.                         /* Put the additional zeroes after the 0x prefix if
  5227.                            (flags & FLAG_ALT) || (dp->conversion == 'p').  */
  5228.                         else if (count >= 2
  5229.                                  && prec_ptr[0] == '0'
  5230.                                  && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X'))
  5231.                           prefix_count = 2;
  5232.  
  5233.                         move = count - prefix_count;
  5234.                         if (precision > move)
  5235.                           {
  5236.                             /* Insert zeroes.  */
  5237.                             size_t insert = precision - move;
  5238.                             TCHAR_T *prec_end;
  5239.  
  5240. # if USE_SNPRINTF
  5241.                             size_t n =
  5242.                               xsum (length,
  5243.                                     (count + insert + TCHARS_PER_DCHAR - 1)
  5244.                                     / TCHARS_PER_DCHAR);
  5245.                             length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
  5246.                             ENSURE_ALLOCATION (n);
  5247.                             length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
  5248.                             prec_ptr = (TCHAR_T *) (result + length);
  5249. # endif
  5250.  
  5251.                             prec_end = prec_ptr + count;
  5252.                             prec_ptr += prefix_count;
  5253.  
  5254.                             while (prec_end > prec_ptr)
  5255.                               {
  5256.                                 prec_end--;
  5257.                                 prec_end[insert] = prec_end[0];
  5258.                               }
  5259.  
  5260.                             prec_end += insert;
  5261.                             do
  5262.                               *--prec_end = '0';
  5263.                             while (prec_end > prec_ptr);
  5264.  
  5265.                             count += insert;
  5266.                           }
  5267.                       }
  5268. #endif
  5269.  
  5270. #if !USE_SNPRINTF
  5271.                     if (count >= tmp_length)
  5272.                       /* tmp_length was incorrectly calculated - fix the
  5273.                          code above!  */
  5274.                       abort ();
  5275. #endif
  5276.  
  5277. #if !DCHAR_IS_TCHAR
  5278.                     /* Convert from TCHAR_T[] to DCHAR_T[].  */
  5279.                     if (dp->conversion == 'c' || dp->conversion == 's')
  5280.                       {
  5281.                         /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING
  5282.                            TYPE_WIDE_STRING.
  5283.                            The result string is not certainly ASCII.  */
  5284.                         const TCHAR_T *tmpsrc;
  5285.                         DCHAR_T *tmpdst;
  5286.                         size_t tmpdst_len;
  5287.                         /* This code assumes that TCHAR_T is 'char'.  */
  5288.                         typedef int TCHAR_T_verify
  5289.                                     [2 * (sizeof (TCHAR_T) == 1) - 1];
  5290. # if USE_SNPRINTF
  5291.                         tmpsrc = (TCHAR_T *) (result + length);
  5292. # else
  5293.                         tmpsrc = tmp;
  5294. # endif
  5295.                         tmpdst =
  5296.                           DCHAR_CONV_FROM_ENCODING (locale_charset (),
  5297.                                                     iconveh_question_mark,
  5298.                                                     tmpsrc, count,
  5299.                                                     NULL,
  5300.                                                     NULL, &tmpdst_len);
  5301.                         if (tmpdst == NULL)
  5302.                           {
  5303.                             int saved_errno = errno;
  5304.                             if (!(result == resultbuf || result == NULL))
  5305.                               free (result);
  5306.                             if (buf_malloced != NULL)
  5307.                               free (buf_malloced);
  5308.                             CLEANUP ();
  5309.                             errno = saved_errno;
  5310.                             return NULL;
  5311.                           }
  5312.                         ENSURE_ALLOCATION (xsum (length, tmpdst_len));
  5313.                         DCHAR_CPY (result + length, tmpdst, tmpdst_len);
  5314.                         free (tmpdst);
  5315.                         count = tmpdst_len;
  5316.                       }
  5317.                     else
  5318.                       {
  5319.                         /* The result string is ASCII.
  5320.                            Simple 1:1 conversion.  */
  5321. # if USE_SNPRINTF
  5322.                         /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a
  5323.                            no-op conversion, in-place on the array starting
  5324.                            at (result + length).  */
  5325.                         if (sizeof (DCHAR_T) != sizeof (TCHAR_T))
  5326. # endif
  5327.                           {
  5328.                             const TCHAR_T *tmpsrc;
  5329.                             DCHAR_T *tmpdst;
  5330.                             size_t n;
  5331.  
  5332. # if USE_SNPRINTF
  5333.                             if (result == resultbuf)
  5334.                               {
  5335.                                 tmpsrc = (TCHAR_T *) (result + length);
  5336.                                 /* ENSURE_ALLOCATION will not move tmpsrc
  5337.                                    (because it's part of resultbuf).  */
  5338.                                 ENSURE_ALLOCATION (xsum (length, count));
  5339.                               }
  5340.                             else
  5341.                               {
  5342.                                 /* ENSURE_ALLOCATION will move the array
  5343.                                    (because it uses realloc().  */
  5344.                                 ENSURE_ALLOCATION (xsum (length, count));
  5345.                                 tmpsrc = (TCHAR_T *) (result + length);
  5346.                               }
  5347. # else
  5348.                             tmpsrc = tmp;
  5349.                             ENSURE_ALLOCATION (xsum (length, count));
  5350. # endif
  5351.                             tmpdst = result + length;
  5352.                             /* Copy backwards, because of overlapping.  */
  5353.                             tmpsrc += count;
  5354.                             tmpdst += count;
  5355.                             for (n = count; n > 0; n--)
  5356.                               *--tmpdst = (unsigned char) *--tmpsrc;
  5357.                           }
  5358.                       }
  5359. #endif
  5360.  
  5361. #if DCHAR_IS_TCHAR && !USE_SNPRINTF
  5362.                     /* Make room for the result.  */
  5363.                     if (count > allocated - length)
  5364.                       {
  5365.                         /* Need at least count elements.  But allocate
  5366.                            proportionally.  */
  5367.                         size_t n =
  5368.                           xmax (xsum (length, count), xtimes (allocated, 2));
  5369.  
  5370.                         ENSURE_ALLOCATION (n);
  5371.                       }
  5372. #endif
  5373.  
  5374.                     /* Here count <= allocated - length.  */
  5375.  
  5376.                     /* Perform padding.  */
  5377. #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
  5378.                     if (pad_ourselves && has_width)
  5379.                       {
  5380.                         size_t w;
  5381. # if ENABLE_UNISTDIO
  5382.                         /* Outside POSIX, it's preferrable to compare the width
  5383.                            against the number of _characters_ of the converted
  5384.                            value.  */
  5385.                         w = DCHAR_MBSNLEN (result + length, count);
  5386. # else
  5387.                         /* The width is compared against the number of _bytes_
  5388.                            of the converted value, says POSIX.  */
  5389.                         w = count;
  5390. # endif
  5391.                         if (w < width)
  5392.                           {
  5393.                             size_t pad = width - w;
  5394.  
  5395.                             /* Make room for the result.  */
  5396.                             if (xsum (count, pad) > allocated - length)
  5397.                               {
  5398.                                 /* Need at least count + pad elements.  But
  5399.                                    allocate proportionally.  */
  5400.                                 size_t n =
  5401.                                   xmax (xsum3 (length, count, pad),
  5402.                                         xtimes (allocated, 2));
  5403.  
  5404. # if USE_SNPRINTF
  5405.                                 length += count;
  5406.                                 ENSURE_ALLOCATION (n);
  5407.                                 length -= count;
  5408. # else
  5409.                                 ENSURE_ALLOCATION (n);
  5410. # endif
  5411.                               }
  5412.                             /* Here count + pad <= allocated - length.  */
  5413.  
  5414.                             {
  5415. # if !DCHAR_IS_TCHAR || USE_SNPRINTF
  5416.                               DCHAR_T * const rp = result + length;
  5417. # else
  5418.                               DCHAR_T * const rp = tmp;
  5419. # endif
  5420.                               DCHAR_T *p = rp + count;
  5421.                               DCHAR_T *end = p + pad;
  5422.                               DCHAR_T *pad_ptr;
  5423. # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
  5424.                               if (dp->conversion == 'c'
  5425.                                   || dp->conversion == 's')
  5426.                                 /* No zero-padding for string directives.  */
  5427.                                 pad_ptr = NULL;
  5428.                               else
  5429. # endif
  5430.                                 {
  5431.                                   pad_ptr = (*rp == '-' ? rp + 1 : rp);
  5432.                                   /* No zero-padding of "inf" and "nan".  */
  5433.                                   if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
  5434.                                       || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
  5435.                                     pad_ptr = NULL;
  5436.                                 }
  5437.                               /* The generated string now extends from rp to p,
  5438.                                  with the zero padding insertion point being at
  5439.                                  pad_ptr.  */
  5440.  
  5441.                               count = count + pad; /* = end - rp */
  5442.  
  5443.                               if (flags & FLAG_LEFT)
  5444.                                 {
  5445.                                   /* Pad with spaces on the right.  */
  5446.                                   for (; pad > 0; pad--)
  5447.                                     *p++ = ' ';
  5448.                                 }
  5449.                               else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
  5450.                                 {
  5451.                                   /* Pad with zeroes.  */
  5452.                                   DCHAR_T *q = end;
  5453.  
  5454.                                   while (p > pad_ptr)
  5455.                                     *--q = *--p;
  5456.                                   for (; pad > 0; pad--)
  5457.                                     *p++ = '0';
  5458.                                 }
  5459.                               else
  5460.                                 {
  5461.                                   /* Pad with spaces on the left.  */
  5462.                                   DCHAR_T *q = end;
  5463.  
  5464.                                   while (p > rp)
  5465.                                     *--q = *--p;
  5466.                                   for (; pad > 0; pad--)
  5467.                                     *p++ = ' ';
  5468.                                 }
  5469.                             }
  5470.                           }
  5471.                       }
  5472. #endif
  5473.  
  5474.                     /* Here still count <= allocated - length.  */
  5475.  
  5476. #if !DCHAR_IS_TCHAR || USE_SNPRINTF
  5477.                     /* The snprintf() result did fit.  */
  5478. #else
  5479.                     /* Append the sprintf() result.  */
  5480.                     memcpy (result + length, tmp, count * sizeof (DCHAR_T));
  5481. #endif
  5482. #if !USE_SNPRINTF
  5483.                     if (tmp != tmpbuf)
  5484.                       free (tmp);
  5485. #endif
  5486.  
  5487. #if NEED_PRINTF_DIRECTIVE_F
  5488.                     if (dp->conversion == 'F')
  5489.                       {
  5490.                         /* Convert the %f result to upper case for %F.  */
  5491.                         DCHAR_T *rp = result + length;
  5492.                         size_t rc;
  5493.                         for (rc = count; rc > 0; rc--, rp++)
  5494.                           if (*rp >= 'a' && *rp <= 'z')
  5495.                             *rp = *rp - 'a' + 'A';
  5496.                       }
  5497. #endif
  5498.  
  5499.                     length += count;
  5500.                     break;
  5501.                   }
  5502. #undef pad_ourselves
  5503. #undef prec_ourselves
  5504.               }
  5505.           }
  5506.       }
  5507.  
  5508.     /* Add the final NUL.  */
  5509.     ENSURE_ALLOCATION (xsum (length, 1));
  5510.     result[length] = '\0';
  5511.  
  5512.     if (result != resultbuf && length + 1 < allocated)
  5513.       {
  5514.         /* Shrink the allocated memory if possible.  */
  5515.         DCHAR_T *memory;
  5516.  
  5517.         memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T));
  5518.         if (memory != NULL)
  5519.           result = memory;
  5520.       }
  5521.  
  5522.     if (buf_malloced != NULL)
  5523.       free (buf_malloced);
  5524.     CLEANUP ();
  5525.     *lengthp = length;
  5526.     /* Note that we can produce a big string of a length > INT_MAX.  POSIX
  5527.        says that snprintf() fails with errno = EOVERFLOW in this case, but
  5528.        that's only because snprintf() returns an 'int'.  This function does
  5529.        not have this limitation.  */
  5530.     return result;
  5531.  
  5532. #if USE_SNPRINTF
  5533.   overflow:
  5534.     if (!(result == resultbuf || result == NULL))
  5535.       free (result);
  5536.     if (buf_malloced != NULL)
  5537.       free (buf_malloced);
  5538.     CLEANUP ();
  5539.     errno = EOVERFLOW;
  5540.     return NULL;
  5541. #endif
  5542.  
  5543.   out_of_memory:
  5544.     if (!(result == resultbuf || result == NULL))
  5545.       free (result);
  5546.     if (buf_malloced != NULL)
  5547.       free (buf_malloced);
  5548.   out_of_memory_1:
  5549.     CLEANUP ();
  5550.     errno = ENOMEM;
  5551.     return NULL;
  5552.   }
  5553. }
  5554.  
  5555. #undef MAX_ROOM_NEEDED
  5556. #undef TCHARS_PER_DCHAR
  5557. #undef SNPRINTF
  5558. #undef USE_SNPRINTF
  5559. #undef DCHAR_SET
  5560. #undef DCHAR_CPY
  5561. #undef PRINTF_PARSE
  5562. #undef DIRECTIVES
  5563. #undef DIRECTIVE
  5564. #undef DCHAR_IS_TCHAR
  5565. #undef TCHAR_T
  5566. #undef DCHAR_T
  5567. #undef FCHAR_T
  5568. #undef VASNPRINTF
  5569.